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;
}

 

posted @ 2018-10-11 12:05  CodingSherlock  阅读(188)  评论(0编辑  收藏  举报