TypeScript 勉強会 Day3

427 Views

September 26, 23

スライド概要

社内で開催した TypeScript 勉強会の Day3 スライドです。Day1 で扱った内容の応用編などを掲載しています。

profile-image

LIFULL HOME'Sを運営する株式会社LIFULLのアカウントです。 LIFULLが主催するエンジニア向けイベント「Ltech」等で公開されたスライド等をこちらで共有しております。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

TypeScript ハンズオン Day3 Fukudome Naohiro 1 © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。

2.

今日のおしながき ● ユニオン型とinキーワード ○ day 1の「ユニオン型」の応用編 ● ユーザー定義型ガード ○ day 1の「型ガード」の応用編 ● Utility Types ○ ジェネリクスを使ったいろんな組み込み型

3.

ユニオンとinキーワード

4.

ユニオン型のおさらい type Id = string | number 既存の型の組み合わせで新しい型を作る Day1資料

5.

オブジェクトの型定義 type MyObject = { keyがstringかnumber、 [Key: string | number] : string } valueがstringのオブジェクト

6.

primitive型以外でやっていきたい //翻訳の対応表の型 type Translate = { [SupportLang: "en" | "ja" | "es" | "de"] : string } //翻訳の具体的な対応表 const translations: Translate = { "en": "Hello", "ja": "こんにちは", "es": "Hola", "de": "Guten Tag", // ↓対応してない言語ではエラーになってほしい "fr": "Bonjour" }

7.

残念ながら //対応している言語 type Translate = { // ↓でエラー [SupportLang: "en" | "ja" | "es" | "de"] : string } //翻訳の対応表 const translations: Translate = { "en": "Hello", "ja": "こんにちは", "es": "Hola", "de": "Guten Tag", // ↓対応してない言語ではエラーになってほしい "fr": "Bonjour" }

8.

そんなあなたに inキーワード✨

10.
[beta]
注意

const car = { make: 'Honda', model: 'Accord', year: 1998 };

// carにmakeプロパティがなければ表示
if ('make' in car !== false) {

if文で使う in とは異なる概念

console.log('どこでつくられたのかわかりません')
}

あくまで型の世界で使う

13.

ユーザ定義型ガード

14.
[beta]
おさらい: 型ガード

function numberOrString(someArg: string | number) {
if (typeof someArg === 'number') {
console.log('変数の型はnumberです');
} else {
console.log(`変数の型は${typeof someArg}です`)
}
}
numberOrString(1) // => "変数の型はnumberです"
numberOrString("str") // => "変数の型はstringです"

変数の型によって
処理を分岐できる機能

15.
[beta]
おさらい: うれしいこと
/**
* 文字列の末尾に"co.jp"を付けくわえる関数

stringではないものに

*/
function tld(domain: string | undefined): string {
if (typeof domain === 'string') {
return domain.concat('.co.jp');

stringのメソッドを使おうとしたとき弾いて
くれる

} else {
// ↓ domainがstringではない => domainはundefined
//

=> concatは存在しない => コンパイルエラー

return domain.concat('.co.jp');
}
}

Playground

16.

自分で定義した型でガードしたい type Foo = { foo: number; common: string; } type Bar = { bar: number; common: string; } function doStuff(arg: Foo | Bar) { if (typeof arg === "Foo") { // argがFoo型だったときの処理 // Fooにしかない値を使いたい console.log(arg.foo); } } 自分で作った型を使って型ガードしたい

17.
[beta]
自分で定義した型でガードしたい
type Foo = {
foo: number;
common: string;
}

残念ながらコンパイルエラーになる
=> Playground

type Bar = {
bar: number;
common: string;
}

エラーメッセージ

function doStuff(arg: Foo | Bar) {
if (typeof arg === "Foo") {
// argはFoo型やな! => エラー
console.log(arg.foo);
}
}

(要約: Fooはtypeofの返り値の型にはありません)
This comparison appears to be unintentional because
the types '"string" | "number" | "bigint" | "boolean"
| "symbol" | "undefined" | "object" | "function"' and
'"Foo"' have no overlap.

18.

そんなあなたに isキーワード✨

19.

ユーザ定義型ガード type Foo = { foo: number; common: string; } type Bar = 省略 // 関数の返り値が true なら仮引数 arg の型は Foo function isFoo(arg: any): arg is Foo { is キーワードで関数を型定義 return arg.foo !== undefined; 中身はbooleanを返すよう実装する } function doStuff(arg: Foo | Bar) { if (isFoo(arg)) { // argはFoo型に確定する console.log(arg.foo); console.log(arg.bar); // barはFooにないのでコンパイルエラー } }

20.

注意 type Foo = { foo: number; common: string; ユーザ定義型ガード用の } function doStuff(arg: Foo | Bar) { // コンパイルエラー if (arg is Foo) { ... } } 関数の型定義だけにしか使えない

21.

クラスと組み合わせてみましょう type Result = Success | Failure // 何らかの処理を行って、SuccessかFailureを返す function doSomething(x: boolean): Result { if (x) { return new Success('success') } else { Result型はSuccessかFailureのどっちか return new Failure('failure') } } SuccessのときとFailureのときで処理を分 const result = doSomething(true) けたいとき if (result.isFailure()) { // 異常系の処理... } else { あると思います // 正常系の処理... }

24.

Utility Types

25.

Utility Types ジェネリクスを活用した 便利な組み込み型 一覧

26.

Pick

27.

Pick型 Pick<T, K> あるオブジェクト型Tから、 Kで指定されたキーだけを取り出す型

28.

例題に困ったので いろんな型パズルが楽しめるリポジトリ type-challenges

29.

Pickを自分で実装してみよう type-challenges #4 改題

30.

デバッグの際には ^? を中身を知りたいところに合わせて書いてみましょう

31.

解答例 解答例