お題
型T
からK
に指定したkey
だけを含むオブジェクトの型を返すユーティリティ型MyPick
を自作する。
やりたいこと
type User = {
name: string;
age: number;
gender: string;
createdAt: string;
};
type NameAge = MyPick<User, "name" | "age">
type NameAge = {
name: string;
age: number;
};
解答
type MyPick<T, K extends keyof T> = {[key in K] : T[key]}
解説
処理の流れ
-
<T, K extends keyof T>
K
がkeyof T
の部分型になるように制約する。 -
{[key in K] : T[key]}
Mapped Typesを利用し、新しいオブジェクトを作成する。
ユーティリティ型とは...
型から別の型を導き出してくれる型のこと。
extendsとは...
- 型引数に制約をつける。
- ジェネリクス型を特定の型に限定することができる。
<T extends string> // 型引数Tはstirng型限定になる。
keyof演算子とは...
- オブジェクトの型からプロパティ名を型として返す型演算子。
type Person = {
name: string;
};
type PersonKey = keyof Person // "name"
- 複数のプロパティを持つ場合は、全てのプロパティ名がユニオン型で返される。
type Person = {
name: string;
age: number;
};
type PersonKey = keyof Person // "name" | "age"
Mapped Typesとは…
- 型の各プロパティを順番に処理する。
- 主にユニオン型と組み合わせて使う(keyofと相性が良い)。
// 基本の形
{Key in X} : Y
インデックスアクセス型とは…
- プロパティの型や配列の要素を参照する。
オブジェクトの型とインデックスアクセス型
- オブジェクト型["プロパティ名"]でプロパティの型を取得できる。
type Person = {
name: string;
};
type PersonIndex = Person["name"] // string
- ユニオン型を使って参照することができる。
type Person = {
name: string;
age: number;
};
type PersonIndex = Person["name" | "age"] // string | number
配列型とインデックスアクセス型
要素を順番に、ユニオン型で返す。
const Array = ["Japan", "France", "Italy"] as const
type ArrayIndex = (typeof Array)[number] // "Japan" | "France" | "Italy"
参考記事
ユーティリティ型
extends
keyof演算子
Mapped Types
インデックスアクセス型
今回の問題