前置き
OSS のコードを読んでいると、私はよく知らない文法を目にします。
この記事は、私がコードを読んでいてナンダコレとなった文法について書いています。
以下、注意点。
※ ナンダコレとなっているのは私が文法を知らないだけです。普段からリリースノートをこまめにキャッチアップしていれば、ナンダコレは起きません。
※ いつものごとく保険をはりますが、正しい記載は公式ドキュメント参照です。この記事で書いていることが正しい可能性は低いです。
ナンダコレとなった文法
HTMLElement
に HTMLDivElement
を代入している文法を見て、ナンダコレとなりました。
declare function create<T extends HTMLElement = HTMLDivElement, U = T[]>(
element?: T,
children?: U
): Container<T, U>;
ジェネリクスの型 T
に対して extends
で型を指定するまではよく使う & 見ますが。
declare function create<T extends HTMLElement>
ジェネリクスの型 T
に対して extends
で型を指定して、さらに、その指定した型に対して、異なる型を代入しています。
declare function create<T extends HTMLElement = HTMLDivElement>
文法の説明
この文法については、TypeScript 2.3 のリリースノートに記載されています。
この文法は、extends
に指定した型に対してデフォルトの型を指定しています。
以下の例だと、T
のデフォルトの型は、Player
型になります。
// デフォルトの型を指定
function hello<T extends string = Player>(arg: T): T
デフォルトの型を指定する記法は、上記の文法が使えるようになる以前は以下のように書いて、同じことを実現していました。
// 以前の記法
function hello<T extends Player>(arg: T): T
function hello<T extends string>(arg: T): T
上記を例にすると、T
は string
型、あるいは、Player
型である必要があり、デフォルトの型を指定する記法と同じことが実現できています。これまでは関数シグネチャを2つ書いていましたが、これを省略して書けるということで嬉しい & 楽しい、ということみたいです。
サンプル
この記法を使う場面としては、hello
関数は基本的には引数に Player
型を受け取るけど(= デフォルトの型)、たまに、それ以外の型の引数(= string
型)も受け取ることがある、みたいな場面で使えるかと思います。
type Player =
| "Bradley"
| "Kyle"
function hello<T extends string = Player>(arg: T): T
function hello<T>(arg: T) {
return arg
}
// Player 型の引数を指定する場合(デフォルトの型)
hello("Bradley")
// string 型の引数を指定する場合(デフォルト以外の型)
hello("Daniel")
まとめ
この件はあまり自信がない...間違っていれば優しく指摘してください。以上、終わり!