Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deep Dive Into TypeScript

Deep Dive Into TypeScript

HTML5Conference 2017 Room A
Deep Dive Into TypeScriptの発表資料です。

More Decks by Taketoshi Aono(青野健利 a.k.a brn)

Other Decks in Programming

Transcript

  1. Agenda  -  What is TypeScript? TypeScriptך稱➜ -  About TypeSystems

    TypeScriptך㘗חאְג -  About LanguageService TypeScriptךIDE؟ه٦زחאְג -  About CustomTransformer TypeScriptךAST乼⡲חאְג -  Roadmap ➙䖓ךٗ٦سوحفחאְג -  Popular Issues 鑧겗ךIssueחאְג
  2. interface Point2D {! x: number;! y: number;! }! ! const

    point = {! x: 0,! y: 0! };! ! function acceptPoint2D(point: Point2D) {}! ! acceptPoint2D(point);!
  3. interface Point2D {! x: number;! y: number;! }! ! const

    point = {! x: 0,! y: 0,! z: 1! };! ! function acceptPoint2D(point: Point2D) {}! ! acceptPoint2D(point);!
  4. class MyClass extends OtherClass implements OtherInterface {! public constructor() {

    super(); }! protected methodFoo() { }! private property: number = 1;! public static methodFoo() { }! private static property = 1;! public get getter() {}! public set setter(value: any) {}! public get set prop() {}! private readonly immutableProp: string = 'a';! }!
  5. enum Enum {! VALUE_A = 1,! VALUE_B, // 2! VALUE_C,

    // 3! }! ! enum Enum {! VALUE_A = 'value'! }! ! Enum.VALUE_A // 'value'! Enum[Enum.VALUE_A] // 'VALUE_A'!
  6. // const修飾するとコンパイル後にリテラル化される const enum ConstEnum {! VALUE = 1,! ...!

    }! const value = ConstEnum.VALUE;! // コンパイル後 => const value = 1;
  7. // Simple assignment.! const a = 0;! ! // Function

    return value.! const b = () => 1;! ! // Callback! const d = (callback: (a: number) => boolean) => {! callback(1);! };! d(x => x === 0);! ! // Best Common Type.! const p2d = { x: 0, y: 0 };! const p3d = { x: 0, y: 0, z: 1 };! const p4d = { x: 0, y: 0, z: 1, t: 0 }! const c = [ p2d, p3d, p4d ]; // { x: number; y: number }[];!
  8. // Generic Array! class MyArray<T> {! private arr: T[];! !

    public push(value: T) { this.arr.push(value); }! }! const numArr = new MyArray<number>();! ! // Constraints! function fn<T>(value: T) {! return value.x + 1; // Error!! }! ! function fn<T extends {x: number}>(value: T) {! return value.x + 1;! }!
  9. // Type Alias! type MyString = string;! ! // Insersection

    Type! type A = { x: number };! type B = { y: number };! type Point2D = A & B;! ! // Union Type! type UnionType = string | number;!
  10. // String Literal Types! type Suit =! 'diamond'! | 'club'!

    | 'spade'! | 'heart';! ! const suit: Suit = 'joker';! // Error !!! ! // Index Type! type StringMap = { [key: string]: string };!
  11. // Tagged Union! interface TypeA { kind: 'type-a'; typeAValue: number;

    }! ! interface TypeB { kind: 'type-b'; typeBValue: string; }! ! function processAB(value: TypeA | TypeB) {! switch (value.kind) {! case 'type-a':! return value.typeAValue;! case 'type-b':! return value.typeBValue;! default:! throw new Error('Undefined type.');! }! }!
  12. // Type Guard! function fn(! x: Element | number |

    boolean! ) {! if (x instanceof Element) {! console.log(x.tagName);! } else if (typeof x === 'boolean') {! console.log(x);! } else {! console.log(x.toFixed(0));! }! }!
  13. // User defined type guard! function isString(x: any): x is

    string {! return typeof x === 'string';! }!
  14. // Type Guard! function fn(! x: Element | string |

    number | boolean! ) {! if (x instanceof Element) {! console.log(x.tagName);! } else if (typeof x === 'boolean') {! console.log(x);! } else if (isString(x)) {! console.log(x.toUpperCase());! } else {! console.log(x.toFixed(0));! }! }!
  15. function test1(): never {! throw new Error('error');! }! ! function

    test2(value: string | number) {! if (typeof value === 'string') {! ! } else if (typeof value === 'number') {! ! } else {! value // value = never! }! }!
  16. enum Test { KEY_1 = 1, KEY_2, KEY_3 }! !

    function test(m: Test) {! switch (m) {! case Test.KEY_1:! return 'key1';! case Test.KEY_2:! return 'key2';! default;! const check: never = m;! // error Test.KEY_3 is not assignable to never.! }! }!
  17. interface MyInterface {! a: string;! b: number;! c: boolean;! }!

    ! type AKeys = keyof MyInterface;! // AKeys = 'a' | 'b' | 'c'!
  18. type MyInterfaceClone = {! [P in AKeys]: MyInterface[P]! };! //

    MyInterfaceClone = {! // a: string;! // b: number;! // c: boolean;! // }!
  19. type MyPromiseInterface = {! [P in AKeys]: Promise<MyInterface[P]>;! }! //

    MyPromiseInterface = {! // a: Promise<string>;! // b: Promise<number>;! // c: Promise<boolean>;! // }!
  20. class Base {! value = 1;! }! ! class Derived

    extends Base {! otherValue = 2;! }! ! class Another extends Base {! anotherValue = 3;! }!
  21. declare let baseArr: Base[];! declare let derivedArr: Derived[];! ! //

    Covariant 共変! baseArr = derivedArr;! ! // Contravariant 反変 Error! // TypeScriptでは認められていない derivedArr = baseArr;!
  22. declare let processDerived: (derived: Derived) => void;! declare let processBase:

    (base: Base) => void;! ! // Bivariant 双変! processDerived = processBase;! processBase = processDerived;! ! // Runtime Error.! processBase(new Another());!
  23. class MyArray<T> {! push(value: T);! }! ! declare let arr:

    MyArray<Derived>;! declare let arr2: MyArray<Base>;! arr2 = arr;! // arr = push(value: Derived);! // arr2 = push(value: Base);!
  24. // main.ts (input)! export const x = "literal name";! const

    y = 1;! export interface A {! [x]: string;! [y]: string;! // error: Interface 'A' has or is using private name '[y]' ! // (when using --declaration)! }!
  25. type B {! [x]: string;! [y]: boolean;! }! let a:

    A;! let b: B;! a = b;! // error: Type 'B' is not assignable to type 'A'. ! // Types of property '[y]' are incompatible.!
  26. Plans -  倜׃ְES Decoratorsך㹋鄲 -  Design Time Decorator e.g. deprecated,

    conditional -  Decorators for (arrow) function expression -  dynamic import׾ろ׭׋import㹑 鎉⟃㢩ך倯岀דך㘗䱿锷 -  䕎㹀纏ؿ؋؎ָٕזַ׏׋㜥さחծ @typesךQuickFix׾䲿爙
  27. function makeTuple<...T>(...ts:...T): ...T {! return ts;! }! ! const ts

    = makeTuple('a', 1, {x: 1});! // ...T = [string, number, {x: number}];!
  28. function f<...T,...U>(ts:...T): [...T,...U] {! let us: ...U = makeTuple('hello', 'world');!

    return [...ts, ...us];! }! const ret = f('html', 5, 'conference');! // ret = ['html', 5, 'conference', 'hello', 'world'];! // ...T = [string, number, string]! // ...U = [string, string];! // [...T, ...U] = [string, number, string, string, string]!
  29. interface MyNumber extends number {}! ! const Positive = {!

    [Symbol.hasInstance](v) {! return typeof v === 'number' && v > 0;! }! }! ! let value = 1;! if (value instanceof Positive) {! // value is Positive;! }!
  30. declare module "mylib/a" {! export * from "mylib/b";! export *

    from "mylib/c";! }! declare module "mylib/b" {! export interface Foo {}! ! export class Bar {! constructor()! do(): Foo! }! }! declare module "mylib/c" {! export class Baz {}! }! declare module "mylib" {! export * from "mylib/a";! }!
  31. declare module "mylib" {! export interface Foo {}! ! export

    class Bar {! constructor()! do(): Foo! }! ! export class Baz {}! }!
  32. type Constructor = new(...args): {};! ! interface MemberDesciptor {! kind:

    "Property"! key: string,! isStatic: boolean,! descriptor: PropertyDescriptor,! extras?: MemberDescriptor[]! finisher?(ctor: Constructor): void;! }!
  33. function classDecorator(! ctor: Constructor,! parent: Constructor,! arrayOfDescriptor: MemberDesciptor[]) {! ...!

    }! ! function memberDecorator(! memberDescriptor: MemberDesciptor! ) {! ...! }!
  34. interface JQuery { ! @@deprecated("...", false) ! selector: string; !

    }! ! @@suppressWarning("disallow-leading- underscore") ! function __init() { ! }!
  35. // 0.ts! export interface foo {}! export class C {}!

    // 1.ts! var p: module("./0");! // ここで型と値両方をimportするのか、 // 型は別でimportするのかとかの問題もある。
  36. ⿫罋 •  https://qiita.com/na-o-ys/items/aa56d678cdf0de2bdd79 •  https://github.com/Microsoft/TypeScript/issues •  https://github.com/Microsoft/TypeScript/wiki •  http://ufcpp.net/study/csharp/sp4_variance.html • 

    https://speakerdeck.com/vvakame/about-typescript-and-language- server-protocol •  https://ja.wikipedia.org/wiki/ %E5%85%B1%E5%A4%89%E6%80%A7%E3%81%A8%E5%8F%8D %E5%A4%89%E6%80%A7_(%E8%A8%88%E7%AE%97%E6%A9%9F %E7%A7%91%E5%AD%A6)