Open7
TypeScript
タグ付けUnion型
- ユニオン型で宣言する型
{...}
に対しプロパティのキーに共通するものを設定しUnionで比較 - class宣言ではなく{...}でオブジェクトを作成するのが主流の為instanceofはあまり適さない
- タグを調べることによって型の判定を行う
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; sideLength: number };
type Rectangle = { kind: "rectangle"; width: number; height: number };
type Shape = Circle | Square | Rectangle;
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.sideLength ** 2;
case "rectangle":
return shape.width * shape.height;
}
}
余談
default節による網羅性チェックが必要ないのは、型付けされた返り値ありの関数
だから。
型エラーが出ない時点で網羅性が担保されていることが分かる。
まとめると
下記の場合にはdefault 説を使った網羅性チェックは不要。
- 関数の返り値の型が明示
- switch分の各CaseでReturnが定義されている場合
- https://typescript-jp.gitbook.io/deep-dive/type-system/discriminated-unions
TSではenumではなくてUnionを使っていこう
enumが今のUnionの仕様によってきているが、過去のTSのenumの名残もあるし積極的にenumを使う必要がない。
関数が受け取るオブジェクトとUnion型
type Options1 = { encoding?: string };
type Options2 = { encoding: string | undefined };
function readfile1(_path: string, options?: Options1): void {
console.log(options?.encoding);
}
function readfile2(_path: string, options: Options2): void {
console.log(options.encoding);
}
readfile1("foo.txt", {}); // 空のオブジェクトを渡せるのはきもちわるい
readfile2("foo.txt", { encoding: undefined }); // 明示されるのでこちらの方が良い
順列型
TypeScriptのclass = インスタンスのインターフェイス定義 + コンストラクタの定義
型リテラルのエイリアスよりもインターフェイスを優先する
モデル化できるものはすべてインターフェイスであるべきだ
5.5の変更でfilter
メソッドの型推論の仕様が変わった。
Mapのキーが同じかどうかは厳密等価(===)で判定される
つまり、nullとundefinedで切り分けたい時に有効