はじめに
- 久しぶりにTypescriptの勉強を再開する
- タイプをモデル化するためのより高度な方法をいくつか調べてみた。
前回の記事
- 下記の記事の続編
Advanced Types
https://www.typescriptlang.org/docs/handbook/advanced-types.html
Intersection Types(交差型)
複数のタイプを1つに組み合わせます。これにより、既存のタイプを追加して、必要なすべての機能を備えた単一のタイプを取得できます。 たとえば、Person&Serializable&Loggableは、PersonおよびSerializable and Loggableです。 つまり、このタイプのオブジェクトには、3つのタイプすべてのすべてのメンバーが含まれます。
AかつB(union型はAまたはB)
- & で指定したすべての型に含まれるものすべてを定義する必要がある。かぶっているものは1つだけ定義する
type Enginner ={ name: string; role: string; } type Twitter = { name: string, follower: number } type EnginnerTwitter = Enginner & Twitter const person: EnginnerTwitter ={ name: 'Yamda', role: 'reader', follower: 200 }
- interface型の場合
interface Enginner { name: string; role: string; } interface Twitter { name: string, follower: number } interface EnginnerTwitter extends Enginner, Twitter = {} const person: EnginnerTwitter ={ name: 'Yamda', role: 'reader', follower: 200 }
- 下記のように記述することが可能。
type test1 = number | boolean type test2 = string | number type test = test1 & test2 ## 数値は入れられるが、文字列は入れれない。 const abc: test = 0
Type Guards
条件文を使って型を絞り込んでいく方法。 www.typescriptlang.org
- typeofの戻り値は「bigint」「boolean」「function」「number」「object」「string」「symbol」「undefined」
function toUpperCase(x: string | number){ if (typeof x === 'string'){ return x.toUpperCase(); }else if(typeof x === 'number'){ return String(x) } }
2) .in演算子
type FreeLance = Enginner | Twitter function profileInfo(freeLance: FreeLance) { console.log(freeLance.name) // オブジェクトにroleプロパティがあるかチェックし、含まれていたらログ出力 if ('role' in freeLance) { console.log(freeLance.role); } // オブジェクトにfollowerプロパティがあるかチェックし、含まれていたらログ出力 if ('follower' in freeLance) { console.log(freeLance.follower); } }
3) . instanseof演算子
class Foo { foo = 123; } class Bar { bar = 123; } function doStuff(arg: Foo | Bar) { if (arg instanceof Foo) { console.log(arg.foo); // OK console.log(arg.bar); // Error! } else { // MUST BE Bar! console.log(arg.foo); // Error! console.log(arg.bar); // OK } } doStuff(new Foo()); doStuff(new Bar());
タグ付きunion / 判別共用体(Discriminated Unions)
- シングルトンタイプ、ユニオンタイプ、タイプガード、タイプエイリアスを組み合わせて、タグ付きユニオンまたは代数的データタイプとも呼ばれる、判別ユニオンと呼ばれる高度なパターンを構築できます。
interface Square { kind: "square"; size: number; } interface Rectangle { kind: "rectangle"; width: number; height: number; } interface Circle { kind: "circle"; radius: number; } type Shape = Square | Rectangle | Circle; function area(s: Shape) { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.height * s.width; case "circle": return Math.PI * s.radius ** 2; } }