TypeScript: Array.prototype.mapでundefinedを取り除いた配列を作成する
こんにちは、いわむらです
今回はTypeScriptを使ってundefinedが含まれない配列を作成する方法をご紹介しようと思います
今回はtypescript v4.6.2で動作検証を進めるのでもし上手く動かない場合はバージョンを確認していただきたいです
undefinedが含まれない配列を作成したいにいたった理由なんですが、あるオブジェクトの特定プロパティのみの配列をループ処理を使って作成したい時に上手くいかずはまってました
サンプルのためにあるオブジェクトを名前プロパティが任意のユーザー型とします
type User = {
/**
*
* @type {number}
* @memberof User
*/
id: number;
/**
*
* @type {string}
* @memberof User
*/
name?: string;
}
ユーザーのリストを作成して名前を抽出した配列を作ろうと思います
まずはユーザーリストを作ります
const user1: User = {
id: 1,
name: 'test1',
} as User
const user2: User = {
id: 2,
name: 'test2',
}
const user3: User = {
id: 3,
name: 'test3',
}
const userList = [user1, user2, user3];
名前のみを抽出するメソッドを作成しようとしてArray.prototype.mapを使ってみるとundefinedが含まれるかもしれないからとエラーになります
const getUserNames = (users: User[]): string[] => {
return users.map((u: User) => u.name)
}
// Type '(string | undefined)[]' is not assignable to type 'string[]'
そこでArray.prototype.filterでundefinedを取り除いてみます
Array.prototype.filterを利用したら上手くいくかと思ったのですがまた同じエラーでコンパイルが通りませんでした
const userNames = (userss: User[]): string[] => {
return userss
.map((u: User) => u.name)
.filter(
(name: string | undefined) => name !== undefined
)
}
Array.prototype.filterの戻り値をユーザ定義型ガードでstringだとすることで解消します
nameにundefinedが含まれているのでundefinedを除いた型であると記述します
const getUserNames = (users: User[]): string[] => {
return users
.map((u: User) => u.name)
.filter(
(name): name is Exclude<typeof name, undefined> => {
return name !== undefined
}
)
}
これでコンパイルエラーがない状態で名前のみをもつ配列が作成できました
今回は文字列のみを対象としましたがidが任意プロパティであっても同じようにすることでnumber[]を返却するメソッドを作成できます
今回は以上になります。最後まで読んでいただきありがとうございました。