TypeScriptでArray.prototype.filterを使って特定の種類の要素を除去する際の注意点
TypeScriptでArray.prototype.filterを使って特定の種類の要素を除去する方法
ジェネリック型とunknown型
この方法は、ジェネリック型とunknown
型を使って、フィルター関数の引数に型ガードを追加します。
function filterOutNumbers<T>(arr: Array<T | number>): Array<T> {
return arr.filter((item): item is T => typeof item !== 'number');
}
const arr: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr = filterOutNumbers(arr); // ["a", "b"]
as演算子
この方法は、as
演算子を使って、フィルター関数の引数に型ガードを追加します。
function filterOutNumbers<T>(arr: Array<T | number>): Array<T> {
return arr.filter((item) => {
const itemAsT = item as T;
return typeof itemAsT !== 'number';
});
}
const arr: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr = filterOutNumbers(arr); // ["a", "b"]
instanceof演算子
class MyClass {}
function filterOutMyClass<T>(arr: Array<T | MyClass>): Array<T> {
return arr.filter((item) => !(item instanceof MyClass));
}
const arr: (string | MyClass)[] = ['a', new MyClass(), 'b'];
const filteredArr = filterOutMyClass(arr); // ["a", "b"]
型エイリアス
type NotNumber<T> = T extends number ? never : T;
function filterOutNumbers<T>(arr: Array<NotNumber<T>>): Array<T> {
return arr.filter((item) => true);
}
const arr: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr = filterOutNumbers(arr); // ["a", "b"]
上記の方法のどれを選択しても、Array.prototype.filter
を使って特定の種類の要素を除去することができます。
// ジェネリック型と`unknown`型
function filterOutNumbers<T>(arr: Array<T | number>): Array<T> {
return arr.filter((item): item is T => typeof item !== 'number');
}
const arr1: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr1 = filterOutNumbers(arr1); // ["a", "b"]
// `as`演算子
function filterOutNumbers<T>(arr: Array<T | number>): Array<T> {
return arr.filter((item) => {
const itemAsT = item as T;
return typeof itemAsT !== 'number';
});
}
const arr2: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr2 = filterOutNumbers(arr2); // ["a", "b"]
// `instanceof`演算子
class MyClass {}
function filterOutMyClass<T>(arr: Array<T | MyClass>): Array<T> {
return arr.filter((item) => !(item instanceof MyClass));
}
const arr3: (string | MyClass)[] = ['a', new MyClass(), 'b'];
const filteredArr3 = filterOutMyClass(arr3); // ["a", "b"]
// 型エイリアス
type NotNumber<T> = T extends number ? never : T;
function filterOutNumbers<T>(arr: Array<NotNumber<T>>): Array<T> {
return arr.filter((item) => true);
}
const arr4: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr4 = filterOutNumbers(arr4); // ["a", "b"]
このコードを実行すると、以下の結果が出力されます。
["a", "b"]
["a", "b"]
["a", "b"]
["a", "b"]
実行環境
- TypeScript 4.7.4
注意事項
- コードを実際に使用する場合は、必要に応じて修正してください。
この方法は、includes
methodを使って、特定の種類の要素を含む要素を除去します。
function filterOutNumbers(arr: Array<string | number>): Array<string> {
return arr.filter((item) => ![1, 2, 3].includes(item));
}
const arr: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr = filterOutNumbers(arr); // ["a", "b"]
reduce method
この方法は、reduce
methodを使って、特定の種類の要素を除去した新しい配列を作成します。
function filterOutNumbers(arr: Array<string | number>): Array<string> {
return arr.reduce((acc, item) => {
if (typeof item !== 'number') {
acc.push(item);
}
return acc;
}, []);
}
const arr: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr = filterOutNumbers(arr); // ["a", "b"]
for loop
function filterOutNumbers(arr: Array<string | number>): Array<string> {
const filteredArr: Array<string> = [];
for (const item of arr) {
if (typeof item !== 'number') {
filteredArr.push(item);
}
}
return filteredArr;
}
const arr: (string | number)[] = ['a', 1, 'b', 2];
const filteredArr = filterOutNumbers(arr); // ["a", "b"]
typescript