はじめに
※この記事を読まれるのは確実に時間の無駄です
それでも見てみよっかなという心優しいお方だけお付き合いください。
記事の内容について
TypeScriptがすでに準備してくれている便利な Utility Types
ですが、無駄に同じような機能を作ってみようと思います。
完全に車輪の再開発で全く意味はありません。
型パズルでただの趣味です。
Pick
「Pick」は既に存在するT型の中からKで選択した一部のプロパティのみを含んだ新たな型を構築します。
Utility Types
まずはTypeScriptの Utility Types
でやってみます。
interface Person {
name: string;
age: number;
}
type PickedType = Pick<Person, 'name'>
結果は以下の通りです。
type PickedType = {
name: string;
}
はい、便利です。
オレオレPick
では自前で実装してみます。
type OrenoPick<T, K extends keyof T> = {
// [key in K] は Mapped Types
// T[key] は Indexed Access Types で K からキャプチャされた key によってアクセス
[key in K]: T[key]
}
interface Person {
name: string;
age: number;
}
type PickedType = OrenoPick<Person, 'name'>
結果は以下の通りです。
type PickedType = {
name: string;
}
Parameters
続いては、Parametersです。
Parametersは関数型Tの引数の型をタプル型として抽出した型を構築します。
Utility Types
まずは、Utility Typesからです。
const foo = (arg: { a: number, b: string }): void => {}
type Hoge = Parameters<typeof foo>;
type Hoge = [arg: {
a: number;
b: string;
}]
オレオレParameters
const foo = (arg: { a: number, b: string }): void => {}
// 「(...args: any[]) => any」を extends することで、Tが関数であるという制約を設ける
type OrenoParameters<T extends (...args: any[]) => any>
= T extends (...args: infer R) =>
unknown ? R : never
type Hoge = OrenoParameters<typeof foo>;
type Hoge = [arg: {
a: number;
b: string;
}]
はい、こちらも一致しました。
infer
については以下の記事で少しだけ解説しておりますのでもし宜しければご参考下さい。
さぁ、次にいきましょう。
Readonly
ReadonlyはTの全てのプロパティをreadonlyのプロパティにしてくれます。
Utility Types
interface Todo {
title: string;
}
const todo: Readonly<Todo> = {
title: "Delete inactive users",
};
todo.title = "Hello"; // Cannot assign to 'title' because it is a read-only property.
オレオレReadonly
type OrenoReadonly<T> = {
// Mapped Types で readonly をつける
readonly [key in keyof T]: T[key]
}
interface Todo {
title: string;
}
const todo: OrenoReadonly<Todo> = {
title: "Delete inactive users",
};
todo.title = "Hello"; // Cannot assign to 'title' because it is a read-only property.
はい、ちゃんと書き込み時にエラーになりました。
ここであることに気づく
UtilityTypes にマウスオーバーすると、めっちゃ親切に内部実装を見せてくれる。。。
定義にジャンプしなくても.d.tsがあるからそりゃそうだよね、
ということで、これ以上やる意味がないと判断し終了いたします。
まぁ、頭の体操にはよかったかな、、、と思うことにします。。
以上です。
最後まで読んで下さった心優しい方に感謝。