奇妙1. Literal type
ある特定のリテラル値である、というような型。
Scalaにも欲しい(Scala 3で入る予定がある)
type EventName = "ready" | "click" | "submit"
type TimeUnit = "day" | "hour" | "minute" | "s" | "ms"
type HttpResponse = 100 | 200 | 404 | ...
let name: EventName = "NGK" // error!!
Slide 21
Slide 21 text
奇妙2. Type Predicate
Union type(A または B、 A | B)のいずれかである
ことを表せる特別なbooleanみたいなもの
function isFish(pet: Fish | Bird): pet is Fish {
return (pet).swim !== undefined;
}
let pet = getSmallPet();
if ((pet).swim) {
(pet).swim();
} else {
(pet).fly();
}
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
キャスト必要
キャスト不要
Type predicateを返すfunction=Type Guard
Slide 22
Slide 22 text
奇妙3. Index type
オブジェクトの持つメンバーを型安全に参照できる。
型TのIndex type=メンバー名のstring literal typeのunion
interface Person {
name: string;
age: number;
location: string;
}
type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[]; // "length" | "push" | "pop" | "concat" | …
Slide 23
Slide 23 text
奇妙4. Indexed access type
Index typeの双対(dual)。
メンバーの型をメンバーの名前で参照できる
type P1 = Person["name"]; // string
type P2 = Person["name" | "age"]; // string | number
type P3 = string["charAt"]; // (pos: number) => string
type P4 = Person["foo"]; // error !!
let myName: P1 = 30; // error!!
Slide 24
Slide 24 text
奇妙5. Mapped type
Index typeとIndexed access typeを組み合わせることで
型TのメンバーPを加工した型をシンプルに定義できる
type Nullable = { [P in keyof T]: T[P] | null }
type Partial = { [P in keyof T]?: T[P] }
type Proxy = {
get(): T;
set(value: T): void;
}
type Proxify = {
[P in keyof T]: Proxy;
}