从实际项目中理解typeScipt

64 阅读3分钟

从实际项目中理解typeScipt

随着越来越多的开源项目拥抱 typeScript,我们现实中接触的业务也会逐渐使用 ty peScript,这里不对 typeScript 是不是多此一举的探讨,更多的是针对实际项目中我们会利用 typeScript 做好哪些

对象类型

场景1

接口A有很多属性,类型B只是接口A的某一个不确定的属性

  1. 手动添加

    interface A {
      id:string
      name:string
      ....
      prop:string
    }
    ​
    type B = 'id' | 'name' | ... | 'prop'
    
  2. 利用keyof

    interface A {
      id:string
      name:string
      ....
      prop:string
    }
    type B = keyof A // 'id' | 'name' | ... | 'prop'
    

场景2

接口A有很多属性,类型B如何获得和接口A一样多的属性

  1. 结合或者继承再Omit不属于的属性

    interface A {
      name:string
      id:string
      age:string
      key:string
    }
    ​
    type B = Omit<A & {
      value:number
    },'value'> 
    ​
    interface B extends A  {
      value:number
    }
    type C = Omit<B,'value'>
    ​
    
  2. 利用keyof

    interface A {
      name:string
      id:string
      age:string
      key:string
    }
    type B = {
      [property in keyof A]:A[property]
    }
    

场景3

接口A有很多属性,现在接口B需要接口A中大部分的属性

  1. 手动添加

    // 过于麻烦
    interface A {
      id:string
      name:string
      ....
      prop:string
    }
    ​
    interface B {
      ....
    }
    
  1. 结合 PickOmit 使用

    // 过于麻烦
    interface A {
      id:string
      name:string
      ....
      prop:string
    }
    ​
    type B = Pick<A,'prop'> // Pick 挑选相应属性  属性B为:prop 
    type C = Omit<A,'prop'> // Omit 过滤相应属性  属性B为:id/name/...
    

DOM类型

场景1

我有一个输入框A,使用这个DOM提示没有value属性

  1. as 断言成 input

    const inputDom = document.getElementById('test') as HTMLInputElement
    

泛型

场景1

我不知道函数A会有哪些参数,或者参数类型有哪些

  1. 泛型处理,由输入的参数推断类型

    function A<T,U>(value:T,name:U){
    ​
    }
    A(19,'jack')
    

场景2

有一个函数A,我们确定我们传入的参数有value 属性,但是使用泛型提示报错

  1. 泛型约束

    function A<T extends {value: number}>(obj:T){
      console.log(obj.value)
    }
    A({value:1})
    

场景3

有一个函数A,它有一些静态属性

  1. 函数泛型定义方法

    type A<T> = {
      desc: string;
      (arg: T): T;
    };
    function doSomething(fn: A<number>) {
      console.log(fn.desc + " returned " + fn(6));
    }
    

场景4

有一个函数A,我们想知道这个函数的返回类型

  1. ReturnType + typeof

    type Predicate = (x: unknown) => boolean;
    type K = ReturnType<Predicate>;
    /// type K = booleanfunction A(count:number){
      if(count < 5) return {count:1,level:'one'}
      if(count >5 && count < 10) return {count:2,text:'two'}
    }
    type AC = ReturnType<typeof A>
    // type AC = {
    //   count: number;
    //   level: string;
    //   text?: undefined;
    // } | {
    //   count: number;
    //   text: string;
    //   level?: undefined;
    // } | undefined
                         
    

场景5

有一个函数A有两个参数,第二个参数是第一个参数对象的属性

  1. keyof实现
interface OBJTYPE  {
  name:string
  id:number
  key:string
}
function A(obj:OBJTYPE,key:keyof OBJTYPE) {
​
}
A({name:'1',id:2,key:'3'},'id')

工具

Partial<Type>

Type下面的所有属性都设置为可选的类型

Required<Type>

Type下面的所有属性都设置为必选的类型

Readonly<Type>

Type下面的所有属性全都设置为只读的类型

Record<Keys,Type>

构造一个对象类型,它所有的key(键)都是Keys类型,它所有的value(值)都是Type类型

interface CatInfo {
  age: number;
  breed: string;
}
​
type CatName = "miffy" | "boris" | "mordred";
​
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

Pick<Type,keys>

Type类型里面挑选属性

Omit<Type,keys>

Type类型里面过滤了一些属性