自分のTypeScript力に全く自信を感じないため、type challenges
をやって現在の自分の立ち位置を確かめようとしましたが、早速easy問題の1問目から挫折したのでアウトプットします。
ちなみに問題は以下です
問題の意味から既にわからずすぐ答えを見たのですが
答えもよくわからず、その理由として自分が今まで目を背けてきたextends
とin
を使用していましたのでこの際ちゃんと勉強しようと思いました。
この記事ではまずextendsについてまとめます。
extendsとは
Genericsで渡される型に対して制約をつけるものだそうです。
例えば以下の関数はジェネリクスに何も制約がついていないのでどんな方でも指定することができます。
今回はboolean型を入れています。
const returnValue = <T>(value: T): T => value;
returnValue<boolean>(true);
ただこのジェネリクスに対して制約をつけることができます。それがextends
です。
以下はextendsを使用してジェネリクスに渡す型をnumber
型とstring
型に限定しています。
const returnValue = <T extends number | string>(value: T): T => value;
ここで
const returnValue = <T extends number | string>(value: T): T => value;
returnValue<boolean>(true);
ジェネリクスにboolean型を渡すと
型を検知して怒ってくれます。
もうちょっと踏み込んでみる
ジェネリクスに制約なしで関数内で引数のプロパティ名を使用しようとするとジェネリクスにプロパティname
があることが担保されていないため怒られます。
ここで以下のようにnameプロパティがある型を作成し、extendsでジェネリクスに渡される型にはname
プロパティがあることを担保してあげるとエラーが消えます。
type Student = { name: string }
const getStudentName = <T extends Student>(student: T): string => student.name
また以下のように渡す型の名前がtypoしていたりするとエラーを出してくれます。
const me = { name: 'cawauchi' }
type ErrorStudentType = { nam: string }
getStudentName<ErrorStudentType>(me)
以下は通ります。
const me = { name: 'cawauchi' }
type AdequateStudentType = { name: string, height?: 176 }
getStudentName<AdequateStudentType>(me)
extendsすごいですね。型エラー出してくれるので業務でも使える部分あったらどんどん使っていきたいです。
参照
強くなりたい!!!!!!!!!!