TypeScript の型システム / Type system of the TypeScript

TypeScript の型システム / Type system of the TypeScript

TypeScript の型の表現力と、言語設計のシンプルさ・巧みさについて話しました。

1a18bf1e50d7d2bdfe52a6c9fceec244?s=128

saiya_moebius

July 31, 2020
Tweet

Transcript

  1. None
  2. XMLHttpRequest

  3. None
  4. None
  5. None
  6. string number undefined null { x: number, y: number }

    string[] [ string, number ] type Hoge = { x: number, y: number };
  7. & type HogeProps = { x: number }; type HugaProps

    = { y: number }; // 2 const props: HogeProps & HugaProps; const props: { x: number, y: number }; & structural typing props
  8. | type Hoge = { // string object hoge: string

    | { id: string, name: string }; }; // undefined const a: string | undefined; const b: { name?: string; // name string | undefined }; | undefined name?
  9. // c name, id const c: { name: string }

    | { id: string }; // c // name, id const d: { name?: string; id?: string }; c
  10. | let a: "Hoge" | "Huga"; a = "Piyo"; //

    Compile error literal type
  11. let a: string | undefined; if (typeof(a) !== "undefined") {

    // a: string // (string | undefined) - undefined == string } else { // a: undefined // (string | undefined) - !(undefined) == undefined }
  12. never never const a: string; if (typeof(a) !== "string") {

    // string - string == never a.substring(0, 1); // Compile error }
  13. type MyEnum = "Hoge" | "Huga"; // JSON MyEnum //

    switch(JSON.parse(`"INVALID VALUE"`) as MyEnum) { case "Hoge": return something; case "Huga": return something; default: throw new Error(a); } | "Piyo"
  14. type MyEnum = "Hoge" | "Huga" | "Piyo"; // JSON

    MyEnum // switch(JSON.parse(`"INVALID VALUE"`) as MyEnum) { case "Hoge": return something; case "Huga": return something; default: throw new Error(a); // "Piyo" ... } | "Piyo" case "Piyo" default default "INVALID VALUE"
  15. /** enum */ class InvalidMyEnumError extends Error { construct(value: never)

    { // = never super(`Invalid value: ${value}`); } } type MyEnum = "Hoge" | "Huga" | "Piyo"; switch(JSON.parse(`"INVALID VALUE"`) as MyEnum) { case "Hoge": return something; case "Huga": return something; default: // case value: never // value: never // Type '"Piyo"' is not assignable to type 'never'. throw new InvalidMyEnumError(value); }
  16. const b: { name: string, address: string } | {

    id: string }; if (typeof(b.name) === "string") { // { name: "hoge", id: "hoge" } // { id: string } if // b // { name: string, address: string } // } { id: string }
  17. const b: { name : string, id?: never , address:

    string } | { name?: never , id : string }; if (typeof(b.name) === "string") { // name string undefined // b: { name: string } } name?: never
  18. | & never

  19. None
  20. // 2 const x: Readonly<{ name: string }>; const x:

    { readonly name: string }; readonly Readonly<T> Readonly<T> Readonly<T> T
  21. const a: readonly string[]; a[0] = " "; // Compile

    error const b = a; b[0] = " "; // Compile error // readonly const c: string[] = a; // Compile error
  22. readonly const

  23. Readonly<T> type Readonly<T> = { readonly [P in keyof T]:

    T[P]; };
  24. keyof type Readonly<T> = { readonly [P in keyof T]:

    T[P]; }; keyof T T keyof { name: string, age: number } "name" | "age"
  25. in type Readonly<T> = { readonly [P in keyof T]:

    T[P]; }; [ in ]: type Hoge = { [P in "name" | "age"]: Error; }; type Hoge = { name: Error; age: Error; };
  26. T[ ] type Readonly<T> = { readonly [P in keyof

    T]: T[P]; }; T[ ] type T = { name: string; age: number; }; type Hoge = { readonly name: T["name"]; readonly age: T["age"]; }; type Hoge = { readonly name: string; readonly age: number; };
  27. type Readonly<T> = { readonly [P in keyof T]: T[P];

    }; keyof T "name" | "age" [P in key of T]: T[P] T["name"] T["age"] readonly
  28. // T Map key, value DeepReadonly ReadonlyMap type DeepReadonly<T> =

    T extends Map<infer K, infer V> ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>> : ... // : DeepReadonly TS infer K V
  29. Compile-time emulation of a 4-bit Virtual Machine using TypeScript's Type

    System
  30. tsconfig.json

  31. None
  32. const hoge = [1, 2]; any any[] number[] [ number,

    number ] [ 1, 2 ] [ number, number... ]
  33. const hoge = [1, 2]; any [1,2] " " undefined

    null any[] [1,2] [] [ " ", null ] number[] [1,2] [] [4,3,2,1,-0] [ number, number ] [1,2] [1024,-3.14] [ 1, 2 ] [1,2]
  34. number[] const hoge /* :number[] */ = [1, 2]; hoge.push(3);

    // Valid hoge[0] = 2.71; // Valid hoge[0] = " "; // INVALID [1, 2]
  35. const myEnumFoo = 0; const myEnumBar = 1; type MyEnum

    = typeof myEnumFoo | typeof myEnumBar; // 0 | 1 // hoge readonly [1, 2] const hoge = [1, 2] as const; // const test0: MyEnum = hoge[0]; // Valid (hoge[0] 1 ) const test1: MyEnum = hoge[1]; // INVALID (hoge[1] 2 ) hoge[0] 1
  36. TypeScript

  37. TypeScript node_modules/**/*.ts transpile only

  38. - -