TypeScript学习笔记-高级类型
交叉类型为将两个类型混合
联合类型表示可以是几种类型之一,用 | 分隔
如果一个值是联合类型,那我们只能访问次联合类型的所有类型的公共成员
可以使用typeof检查基础类型和instanceof来详细类型
typescript会把null和undefined区别对待
nul和undefined是所有其他类型的一个有效值
声明了--strictNullChecks 标记后,当你声明一个变量时,他不会自动的包含null和undefined。而可选参数和可选属性会被自动的加上undefined
去除null的手段
(1)类型保护(prop ==null)
(2)断言prop!.length
类型别名和接口的区别
(1)类型别名不能被extends和implements
/** * 交叉类型 */ function extend<T,U>(first : T,second : U) : T&U { let result = <T&U>{}; for (let id in first) { (<any>result)[id] = (<any>first)[id]; } for(let id in second) { if(!result.hasOwnProperty(id)) { (<any>result)[id] = (<any>second)[id]; } } return result; } /** * 联合类型 */ interface Fish{ swim(); layEggs(); } interface Bird{ fly(); layEggs(); } function getSmallPet():Fish | Bird{ //.... } let pet=getSmallPet(); //只能访问联合类型中所有类型的公共成员 pet.swim(); pet.layEggs(); //要想让它正常工作,需要使用类型断言 if((<Fish>pet).swim){ (<Fish>pet).swim(); }else{ (<Bird>pet).fly(); } //用户自定义的类型保护 //pet is Fish 类型谓词,paramName is Type这种形式 function isFish(pet: Fish|Bird): pet is Fish{ return (<Fish>pet).swim !== undefined; } /** * 类型别名 */ type Name = string; type NameResolve = () => string; type NameOrNameResolve = Name | NameResolve; function getName(n: NameOrNameResolve) : Name { if(typeof n === 'string'){ return n; }else{ return n(); } } /** * 字符串字面量类型 */ type Easing = "ease-in" | "ease-out" | "ease-in-out"; class ElementUI{ animated(dx: number,dy: number,easing:Easing){ if(easing === "ease-in"){ }else if(easing === "ease-in-out"){ }else if(easing === "ease-out"){ } } } let button = new ElementUI(); button.animated(0,0,"ease-in"); button.animated(0,0,"ease-in-out") /** * 可辨识联合 */ interface Circle { kind: 'circle'; radius: number; } interface Square { kind: 'square'; size: number; } interface Rectangle { kind: 'rectangle'; width: number; height: number; } type Shape = Circle | Square | Rectangle ; function computed(shape:Shape):number{ switch(shape.kind){ case 'circle':return Math.PI*shape.radius**2; case 'rectangle':return shape.width*shape.height; case 'square':return shape.size*shape.size; } } /** * 多态的this类型 */ class BasicCaculate{ public constructor(protected value : number = 0){} public currentValue() : number { return this.value; } public add(operand : number) : this { this.value+=operand; return this; } public multiply(operand : number) : this { this.value*=operand; return this; } } let v=new BasicCaculate(2).multiply(1).add(5).currentValue(); //继承 class ScientificCalculate extends BasicCaculate{ public constructor(value = 0){ super(value); } public sin() : this{ this.value=Math.sin(this.value); return this; } } let s=new ScientificCalculate(4).multiply(2).add(3).sin().currentValue(); /** * 索引类型 * key0f T 索引类型查询操作符 * 对于任何T类型,keyof T的结果为T上已知的公共属性名的联合 */ function plunk<T,K extends keyof T>(o:T,names:K[]): T[K][]{ return names.map(n => o[n]); } interface Person{ name:String; age:number; } let person:Person = { name:'edward', age:23 }; let strings:String[] = plunk(person,['name']); function getProperty<T,K extends keyof T>(o:T,names:K):T[K]{ return o[names]; } /** * 映射类型 * K in P,与索引类型一样,内部使用了for...in */ type Keys='option1' | 'option2'; type Flags={[K in Keys]:boolean}; type ReadOnly<T> = { readonly [P in keyof T] : T[P]; } type Partials<T> = { [P in keyof T]? : T[P]; } //包装类型 type Proxy<T> = { get():T; set(value : T) : void; } type Proxify<T> = { [P in keyof T] : Proxy<T[P]>; } function proxify<T>(O : T) : Proxify<T> { } //拆包,反向推断 function unproxify<T>(t : Proxify<T>) : T{ let result = {} as T; for (const k in t) { result[k] = t[k].get(); } return result; }