OPY-bbt / OPY-bbt.github.io

my webpage
https://opy-bbt.github.io/
0 stars 0 forks source link

typescript #32

Open OPY-bbt opened 4 years ago

OPY-bbt commented 4 years ago
OPY-bbt commented 4 years ago

强类型与弱类型

静态类型语言和动态类型语言

OPY-bbt commented 4 years ago

对象类型接口

在使用时,如果遇到对象字面量不符合接口的情况,可使用一下三种方式解决 example:

// 1. 增加字符串索引签名
interface List {
    id: number;
    name: string;
    [x: string]: any;
}

interface Result {
    data: List[]
}

function render(result: Result) {}

//2. 赋值给变量
const result = {
    data: [
        {id: 1, name: 'a'},
        {id: 2, name: 'b'},
    ]
};

render(result);

//3. 类型断言
render({
    data: [
        {id: 1, name: 'a'},
        {id: 2, name: 'b', x: 1},
    ]
} as Result);

render(<Result>{
    data: [
        {id: 1, name: 'a'},
        {id: 2, name: 'b', x: 1},
    ]
});
OPY-bbt commented 4 years ago

函数接口类型

1

let add: (x: number, y: number) => number;
add = (x, y) => x+y;

2

interface Add2 {
    (x: number, y: number): number
}
let add2: Add2 = (x, y) => x + y;

3

type Add3 = (x: number, y: number) => number;
let add3: Add3 = (x, y) => x + y;
OPY-bbt commented 4 years ago

混合类型

// Lib是个函数并且有两个属性
interface Lib {
    (): void;
    doSomething(): void;
    version: string;
}

let lib: Lib = (() => {}) as Lib;
lib.doSomething = () => {};
lib.version = '1.0.0';
OPY-bbt commented 4 years ago

函数重载

先定义不同函数声明列表,然后在一个类型宽泛的版本中实现

function add(...rest: number[]): number;
function add(...rest: string[]): string;
function add(...rest: any[]): any {
    if (typeof rest[0] === 'string') {
        return rest.join();
    } else {
        return rest.reduce((s, n) => s + n)
    }
}
OPY-bbt commented 4 years ago

类型保护

当无法判断运行时变量的类型有用

enum Type { Strong, Week }

class Java {
    helloJava() {
        console.log('java');
    }
}

class JavaScript {
    helloJavaScript() {
        console.log('javascript');
    }
}

function getLanguage(type: Type) {
    let lang = type === Type.Strong ? new Java() : new JavaScript();

    if (lang.helloJava) {
        lang.helloJava();
    } else {
        lang.helloJavaScript();
    }
}

如此的话,会得到ts错误 Property 'helloJava' does not exist on type 'Java | JavaScript'. 可以在getLanguage函数中使用类型断言解决这个问题, 比如 lang as Java,但是typescript也提供类型保护来解决这个问题。

TypeScript能够在特定的区块中,保证变量属于某种特定的类型

可以声明一个函数,将返回值设为类型位词

function isJava(lang: Java | JavaScript): lang is Java {
    return (lang as Java).helloJava !== undefined;
}
OPY-bbt commented 4 years ago

索引类型

interface O {
    a: number,
    b: string,
}

// keyof
// key: 'a' | 'b'
let key: keyof O;

// T[K]
let value: O['a'];

let obj = {
    a: 1,
}

function getValues1(obj: any, keys: string[]) {
    return keys.map(key => obj[key]);
}

function getValues2<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
    return keys.map(key => obj[key]);
}

getValues1(obj, ['b']);
getValues2(obj, ['b']); // error: Type 'string' is not assignable to type '"a"'
OPY-bbt commented 4 years ago

映射类型

interface Obj {
    a: string
    b: string
}

// 将所有的属性变为只读
type ReadonlyObj = Readonly<Obj>

// 变为可选的
type PartialObj = Partial<Obj>

// 抽取
type PickObj = Pick<Obj, 'a'>

// type RecordObj = {
//     x: Obj;
//     y: Obj;
// }
type RecordObj = Record<'x' | 'y', Obj>
OPY-bbt commented 4 years ago

模块

TypeScript 支持CommonJs和ES6模块,并且提供了混用方法

// module a
export = function log() {console.log('dd');}

// module b
import log = require('./a'); //or: import log from './a';
log();
OPY-bbt commented 4 years ago

声明合并

interface A {x: number}
interface A {y: number}

const a: A = {
    x: 1,
    y: 2,
}