『プログラミングTypeScript』 第四章 - is メソッドの実装
『プログラミングTypeScript』の第四章の練習問題に次のようなものがある。
- 型安全なアサーション関数、isを実装してください。型で概略を記述することから始めます。これは、完成したら、次のように使えるものです。
// stringとstringを比較します is('string', 'otherstring') // false // booleanとbooleanを比較します is(true, false) // false // numberとnumberを比較します is(42, 42) // true // 異なる型同士を比較すると、コンパイル時エラーになります is(10, 'foo') // エラー TS2345: 型 '"foo"' の引数を型 'number' の // パラメーターに割り当てることはできません。
よしよし、そんなに難しくはなさそうだ。この章の後半で出てきたジェネリック型を使えばできるのだろう。こうかな?
function is<T>(first: T, second: T) {
return first === second;
}
動いているようだな。おっ、この問題には続きがあるようだ...
// [難問]任意の数の引数を渡せるようにします
is([1], [1, 2], [1, 2, 3]); // false
ふむふむ、何個の引数が渡されるかわからないのであれば、レストパラメーターを使えばいけるだろう。俺は詳しいんだ。
function is<T>(first: T, ...rest: T[]) {
return rest.every(_ => _ === first);
}
うんうん、これも期待通りに動くな。ここで本の解答を眺めると...あれ、ちょっと僕の書いたものとは違う。
function is<T>(first: T, ...rest: [T, ...T[]]): boolean {
return rest.every(_ => _ === first)
}
...あっ、なるほど。もとの ...rest: T[]
だと is('foo')
のような入力も許されてしまうのか...これは失態だ。rest
が少なくともひとつの要素をもつことを保証するためには ...rest: [T, ...T[]]
のように書く必要がある。
こういうケースには自分で気づけないといけないな。