TypeScript Array.prototype.every の型推論
配列のeveryを使うときに、型を狭めてほしいところで、TypeScriptがうまく推論してくれないことがあります。
const numbersOrStrings: (number | string)[] = [1, 2, 3, 4];
if(numbersOrStrings.every(v => typeof(v) === 'number')) {
const _numbers: number[] = numbersOrStrings; // Type '(string | number)[]' is not assignable to type 'number[]'.
// ...
}
numbersOrStrings は number または string の配列です。
これを every を使ってすべての要素が number であるかをチェックしています。
普通に考えると if が true ならすべての要素が number であることが期待されますが、TypeScript は string | number のままとします。
これを回避したい場合は、Type ガードを使います。
const isNumber = (x: unknown): x is number => typeof(x) === "number"
const numbersOrStrings: (number | string)[] = [1, 2, 3, 4];
if(numbersOrStrings.every(isNumber)) {
const _numbers: number[] = numbersOrStrings;
// ...
}
TypeScript 3.X のときは上記のように Type ガードを使ってもエラーになっていました。
4.X からType ガードを使った際に型が狭められるようになったようです。
以下がPRです。
最近のコメント