TypeScript Tutorial 2

this type

Case:

let input: HTMLInputElement;

input.addEventListener('change', function(evt) {
    console.log(this.value); // OK
    console.log(this.naturalWidth); // Error
});

let img: HTMLImageElement;
img.addEventListener('click', function(evt) {
    console.log(this.naturalWidth); // OK
    console.log(this.value); // Error
});

lib.d.ts

interface HTMLInputElement extends HTMLElement {
    // ...
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;
}

Function Overloads

Case:

let input = document.createElement('input');
input.value; // OK
input.naturalWidth; // Error

let img = document.createElement('img');
img.naturalWidth; // OK
img.value; // Error

How-to:

function giveMe(type: 'number'): number;
function giveMe(type: 'string'): string;
function giveMe(type: 'array', ofType: 'number'): Array<number>;
function giveMe(type: 'array', ofType: 'string'): Array<string>;
function giveMe(type: 'number' | 'string' | 'array', ofType?: 'number' | 'string'): any {
    if (type === 'number') {
        return 1;
    } else if (type === 'string') {
        return '1';
    } else if (type === 'array') {
        if (ofType === 'number') {
            return [2];
        } else if (ofType === 'string') {
            return ['2'];
        }
    }
}

/** OK start */
giveMe('number').toFixed(1);
giveMe('string').charAt(1);
giveMe('array', 'number')[0].toFixed(1);
giveMe('array', 'string')[0].charAt(1);
/** OK end */

/** Error start */
giveMe('number').charAt(1);
giveMe('string').toFixed(1);
giveMe('array', 'array');
/** Error end */

Module Augmentation

Example 1:

// bridge.ts
export {};
declare global {
    interface Window {
        bridge: {
            sendCommand: (command: string, data?: any) => void;
        };
    }
}
Window.prototype.bridge = {
    sendCommand: function(command: string, data?: any) {
        console.log('send command', command, data);
    }
}

// app.ts
window.bridge.sendCommand('hello');

Example 2:

// f7-vue.d.ts
declare module "vue" {
    interface Vue {
        $f7: {
            alert(text: string, title?: string);
        };
    }
}

// app.vue
this.$f7.alert('hello');

tsconfig.json

详细介绍请看官网文档

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "lib": [
      "dom",
      "es2015"
    ]
  }
}