TSLab【第8回 TypeScript勉強会】型の再利用と型パズル

TSLab
  • URLをコピーしました!

こんにちは!RYOTAです!

ご覧いただきありがとうございます!

当記事はTSLab勉強会(定例会)のレポート記事になります!

目次

はじめに

私が運営しているTSLabの第8回TS定例会の実施ログとなります。

今回のテーマは「型の再利用と型パズル」です!

第7回の内容は下記の記事にまとめていますので気になる方はあわせてご覧くださいませ。

あわせて読みたい
TSLab【第7回 TypeScript勉強会】オブジェクト型の制御と汎用的な型制御 こんにちは!RYOTAです! ご覧いただきありがとうございます! 当記事はTSLab勉強会(定例会)のレポート記事になります! 【はじめに】 私が運営しているTSLabの第7回定...

ディスカッション内容

インデックスアクセス

オブジェクト型に対してインデックスを指定することで、指定プロパティのvalueの型を取得します。

Type[“property”] の形でアクセスすることが可能です。

type TestObject = { 
    a: number; 
    b: string; 
    c: boolean 
};

type TestA = TestObject["a"];
// type TestA = number

type TestB = TestObject["b"];
// type TestB = string

type TestC = TestObject["c"];
// type TestC = boolean

条件付き型 (継承判定)

今回初めて知ったのがこちら。

型定義時に、三項演算子で型を分岐できるらしい。(マジか。)

それに加え、条件にextendsを用いることで、継承関係をチェックして三項演算子で分岐できるよう。(マジか。)

interface A {
  a: string;
}

// B は A をextendsしたもの 
interface B extends A {
  b: number;
}

interface C {
  c: boolean;
}

// B は A からextendsされたものなので判定が true になる
type Test1 = B extends A ? number : string;
// type Test1 = number

// C は A からextendsされたものではないので判定が false になる
type Test2 = C extends A ? number : string;
// type Test2 = string

TypeScriptは表現の幅が広くて本当に凄いですね。

ただ、こちらは実際のユースケースが想像できないので、”こんなケースで使えるよ”等がございましたら是非教えていただけると助かります。

条件付き型 (プロパティ判定)

ジェネリクス内で extends を用いることで、プロパティの存在チェックをし、存在した場合はそのプロパティのvalueの型を返す条件。(だいぶややこしくなってきた。)

下記の例だと、PropertyA で T[“a”]というプロパティにアクセスしているので、TestA 型ではstringが返りますが、TestB型では a というプロパティが存在しないので、定義時にエラーを返してくれるみたいです。

type PropertyA<T extends { a: unknown }> = T["a"];

interface TestA {
  a: string;
}

interface TestB {
  b: string
}

type TestAPropertyContents = PropertyA<TestA>;
// type TestAPropertyContents = string

type TestBPropertyContents = PropertyA<TestB>;
// エラー: Type 'TestB' does not satisfy the constraint '{ a: unknown; }'. Property 'a' is missing in type 'TestB' but required in type '{ a: unknown; }'

infer句

議題の中でinferを取り扱っている箇所があり、全体で話したのですが結論、よく分かりませんでした。(笑)

こちらは追い追い触れていこうと思います。

下記の記事で詳しく書かれていたのでご参考までに。

型マッピング

今回の勉強会で一番話が上がっていたのがこのマッピング。

下記は[Property in keyof Type] で オブジェクトのプロパティをmapしつつ、型をbooleanに変更した新しいオブジェクト型を生成しています。

type OnlyBooleans<Type> = {
  [Property in keyof Type]: boolean;
};

type StringsAndNumbers = {
  hoge: string
  fuga: number
}

type Booleans = OnlyBooleans<StringsAndNumbers>
// type Booleans = {
//     hoge: boolean;
//     fuga: boolean;
// }

これは実務でも結構使えそうですね。

マスター出来れば一気に表現の幅が広がると思います。

オブジェクトの余剰プロパティチェック

参加者のかっつさん(Twitter)が余剰プロパティチェックについて、全体に発表してくださいました。

余剰プロパティチェックとはバックエンド側でよく行う処理になるのですが、かっつさんが簡単に説明してくださっていましたので引用させていただきます。

オブジェクト型に存在しないプロパティをもつオブジェクトの代入を禁止する行為のこと

https://qiita.com/ka25012/items/6cbc7b515a4f2728ee9d

こちらの内容については実際の記事を見ていただいた方が分かりやすいので、下記のリンクから是非ご覧ください。

かっつさん(Twitter)、これで実務経験4ヶ月ってヤバすぎませんか…?

自作 Utility Types (型パズル)

今回盛り上がったのがこちらの内容。

参加者のTaigaさん(Twitter)がなかなかに激しめの型パズルを作成して、全体に発表してくださいました。

今回の議題の「Indexed Access Types」「Conditional Types」「Mapped Types」を全て組み合わせた内容となっています。

解けた方は是非リプにてご回答を!

私自身、解説いただいてようやく理解できたのですが、これをお遊びで作ってきちゃうのがヤバいですね。(語彙力)

おわりに

今回で8回目の勉強会になりますが、だいぶレベルが上がってきましたね…

ここまで来るとジェネリクスを理解していること前提で進むので気合い入れないとキツイ…

にしても、皆さんレベルが高くて私自身、着いていくので精一杯です…(汗)

という訳で今回は「型の再利用と型パズル」会でした!

最後までご覧いただきありがとうございます!

一緒にTypeScriptを学びたい方はぜひ下記のアカウントからご連絡ください!

TSLab

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次