联合类型和类型保护 使用ts断言进行类型保护 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 interface Dog { canRun : boolean ; bark : () => {}; } interface Cat { canRun : boolean ; miaow : () => {}; } function testAnimal (animal: Dog | Cat ) { if (animal.canRun ) { (animal as Dog ).bark () } else { (animal as Cat ).miaow () } }
使用in关键字进行类型保护 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 interface Dog { canRun : boolean ; bark : () => {}; } interface Cat { canRun : boolean ; miaow : () => {}; } function testAnimal2 (animal: Dog | Cat ) { if ("bark" in animal) { animal.bark () } else { animal.miaow () } }
使用typeof关键字进行类型保护 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 type NumOrString = string | number ;function add (first: NumOrString, second: NumOrString ): NumOrString { if (typeof first === "string" || typeof second === "string" ) { return `${first} ${second} ` } else { return first + second } }
使用instanceof关键字进行类型保护 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class NumberObj { constructor (public count: number ) { } } function addObj (first: object | NumberObj, second: object | NumberObj ) { if (first instanceof NumberObj && second instanceof NumberObj ) { return first.count + second.count } return 0 }
泛型 泛型可以理解为一个占位符,用来表示类型,当我们调用函数时,再传入具体的类型
泛型函数 1 2 3 4 5 6 7 8 9 10 function getResult<T>(params : T, items : T): T { if (typeof params === 'number' ) { return params; } else { return items; } } getResult<number >(123 , 456 ); getResult<string >('123' , '456' );
泛型类 1 2 3 4 5 6 7 class GenericNiumber <T> { value : T; constructor (value: T ) { this .value = value; } }
泛型接口 1 2 3 4 5 6 7 8 9 interface GenericIdentityFn <T, K> { name : T; age : K; } function identity (params: GenericIdentityFn<string , number > ) { return `${params.name} ${params.age} ` }
泛型约束 1 2 3 4 5 6 7 8 9 interface Lengthwise { length : number ; } function loggingIdentity<T extends Lengthwise >(arg : T): T { console .log (arg.length ); return arg; }
使用泛型约束 T extends Lengthwise
,表示 T
必须是满足 Lengthwise
接口要求的类型。
泛型约束中使用类型参数 1 2 3 4 5 6 7 function getProperty<T, K extends keyof T>(obj : T, key : K) { return obj[key]; }
命名空间-namespace 命名空间的使用 TypeScript 的命名空间只对外暴露需要在外部访问的对象,命名空间内的对象通过 export 关键字对外暴露
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 namespace Index { class Header { constructor ( ) { const elem = document .createElement ('div' ); elem.innerText = 'this is header' ; document .body .appendChild (elem); } } class Content { constructor ( ) { const elem = document .createElement ('div' ); elem.innerText = 'this is content' ; document .body .appendChild (elem); } } class Footer { constructor ( ) { const elem = document .createElement ('div' ); elem.innerText = 'this is footer' ; document .body .appendChild (elem); } } export class CreatePage { constructor ( ) { new Header (); new Content (); new Footer (); } } }
外部通过new Index.CreatePage()
调用
多文件的命名空间 像普通的 JS 模块文件可以相互引用一样,包含 namespace 的命名空间文件也可以相互引入,还可以组合成一个更大的命名空间,下面是一个简单的示例,所有文件都在同一目录下,你也可参考官方示例:
Utils.ts
1 2 3 4 5 6 namespace Utils { export interface IAnimal { name : string ; say (): void ; } }
animal.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 export namespace Animal { export class Dog implements Utils .IAnimal { name : string ; constructor (theName: string ) { this .name = theName; } say ( ) { console .log (`${this .name} : 汪汪汪` ) } } }
Index.ts
1 2 3 4 import {Animal } from './animal' ;const he = new Animal .Dog ('Jack' );he.say ();
将多个文件合并 修改tsconfig.json
文件
1 2 "outFile" : "./build" , "module" : "amd" ,