に公開
TypeScriptのextendsについての学習のメモ。
※extendsの継承については今回は触れません。
このextendsを使用すれば、型引数に制約をかける事が可能になります。
ではでは順を追って説明していきます。
・型引数を持つ型(ジェネリック型)について
type User<T> = {
name: string;
age: T;
};
・型引数に制約をつける
上のUser型はnameはstring型ですが、ageに関しは任意に型を取れるようにしています。
※ 年齢の場合はnumber。年齢を内緒にしたい人のために"secret"のようなstringも取れるようにしています。
ただ上のUser型のままだと、型引数としてnumber、string以外に配列など思わぬ型も許容してしまうことになります。
こういうケースで使用できるのがextendsになります。
上記の型引数にextendsを使用して、制約をつけます。
type User<T extends number | "secret"> = {
name: string;
age: T;
};
こうすることでageは"number(実年齢)"か"secret"しか取れなくなります。
また、関数の引数の型に制約をかけることも可能です。
// userのnameを返すだけの関数
const getUserName = <T enxtends User>(user: T) => user.name;
上のようにgetUserNameの引数の前に"TはUserの部分型である"という制約をかけることで、
user.nameがあることを担保することが可能です。
※ 制約なしの<T>のみだとerrorになります。
・conditonal Typesにextendsを使用する
conditional Typesでextendsを使用する際は以下のような構文を取ります。
X enxtends Y ? S : T
これは"XがYの部分型であればSになり、そうでなければTをとるといった意味になります。
具体的に見ていきます。
// TがnumberならNameOrIdは、IdLabel
// TがsringならNameorIdは、NameLabel
type NameOrId<T extneds number | string> = T extends number ? IdLabel : NameLabel;
このように Tがstringの部分型かnumberの部分型かによって、NameOrIdの型が変化するものができます。
こちらはユニオン型を使用して、"どっちの部分型か?"のチェックをしていますが、下記のように"指定した型の部分型かどうか?(条件を満たしているか)"のパターンにも使用されます。
type Animal = {
name: string;
};
type Human = {
name: string;
language: string;
};
type U = Human extends Animal ? true : false;
// type U: true; になります
Human型はAnimal型の部分型になるのでUはtrueになります。