Typescript高级类型大白话

107 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

可以为null的类型

在JavaScript中  null和 undefined 可以复制给其他的类型 在TypeScript中  null和 undefined 不能随意赋值给其他类型

//strict
let s = "foo";
s = null; // err
let sn: string | null = "bar";
sn = null; // ok
sn = undefined; // error,

当然上面这种情况是在开启ts的严格模式下的错误提示,如果是非严格是可以进行赋值的

可选参数

function f(x: number, y?: number) {
    return x + (y || 0);
}
f(1, 2);
f(1);
f(1, undefined);
f(1, null);//err

可选参数在当前情况下可以为undefined,相当于我们对参数或者属性加上了|undefined的操作

类型别名

类型别名可以看成是一个接口但是它又可以联合多个接口

type mytype = mytype1&my2
interface mytype1{
    age:number
}
interface my2{
    add:number
}
let n1:mytype&mytype1 = {
    add:111,
    age:111
}
type tt = {
    name:number
}
let n2:tt={
    name:22
}

可以单独利用type来当成一个接口,也可以用type来联合俩个已经写好的接口

类型别名的泛型

type tree<T> = {
    value:T,
    leftTree:tree<T>,
    rightTree:tree<T>,
}

类型别名也可以使用泛型来定义,用法和接口一样,官方文档上的这个递归写法第一眼看起来有点难懂,但我们可以给它转换一下

let tt:tree<number> = {  
    value:1,
    leftTree:{
        value:2,
        leftTree:{},
        rightTree:{}
    },
    rightTree:{
        value:2,
    },
}

可辨识联合&&完整校验

interface Square {
    kind: "square";
    size: number;
}
interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}
interface Circle {
    kind: "circle";
    radius: number;
}
type Shape = Square | Rectangle | Circle;
function area(s: Shape){
    switch (s.kind) {
        case "square": return s.size * s.size;
        case "rectangle": return s.height * s.width;
    }
    default:return caseMiss(s)
}
function caseMiss(s:never):never{
    throw new Error("Unexpected object: " + x);
}

在接口中声明一个kind来做一个辨识符,用类型别名联合三个接口,也就类型Type需要满足三个接口其中的一个,接着在switch中识别参数用的不同的接口进行不同的操作

caseMiss在这里是对Shape存在的但是缺少的类型做一个判断,当case声明少了情况的时候需要抛出一个异常

索引类型

索引类型查询操作符keyof可以查询类型的属性,这里keyof T是keyof Preson

keyof Person等于 ’name‘|’age‘

T指的是传进来的一个类型 K指的是’name‘|’age‘

(o:T,names:K[])指的是传入的o对应应该类型,names是对应类型下面的参数

比如我们传入person的类型是Person,那么names应该是一个K的数组,所以这里传入的是['name'],也可以是[‘name’,‘age’],单由于strings指定的是string的数组,所以不能传入age,因为age的值会返回一个数字的值

索引访问操作符 T[K][] 表示的是返回一个的数组:可以看作是person['name']:结果是 ['Jarid']

function pluck<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: 'Jarid',
      age: 35
  };
  let strings: string[] = pluck(person, ['name']); // ok, string[]
  console.log(strings)