ts中内置类型

ts中的条件类型

  • 什么是条件类型,就是满足某个条件给一个类型,不满足则给另外一个类型

举例说明:

interface Fish{
    name:string,
    type:'鱼'
}

interface Bird {
    name:string,
    type:'鸟'
}

interface Swiming{
    swiming:string
}

interface Sky {
    sky:string
}
type MyType<T> = T extends Bird ? Sky:Swiming
type IEnv = MyType<Fish>

思考:那么上面中type IEnv得到的是什么类型

  • 解析:传入的Fish,那么他就不满足Bird类型,就得到类型type IEnv =
    Swiming,就好比我们常规的三元表示式一样,满足一个条件得到前面,否则就得到后面的
type IEnv = Swiming

针对上面的例子,再次提问:如果我们传入是Fish | Bird这种格式,那么得到的是什么

type IEnv = MyType<Fish | Bird>
  • 解析:得到的结果如下
type IEnv = Swiming | Sky

为什么会得到上面的结果,那就是 | 符号是可以分发的,如果是传入的是一个联合类型,他会进行条件分发,就好像下面这样,那么我们也可以理解到为什么可以得到上面的结论了。

Fish extends Bird |  Bird  extends Bird

再次提问,如果我传入的是下面情况,会得到什么:

type IEnv = MyType<Fish & Bird>

解析:

type IEnv = Sky
  • 为什么会得到IEnv=sky呢?Fish & Bird是不会进行条件分发的,Fish & Bird得到的类型是never
  • never是所有类型的子类型,never被认为是空的联合类型,也就是说,没有联合项的联合类型,所以还是满足上面的分配律

内置条件类型

1.Exclude

  • Exclude,就好像他的名字一样,在多个类型中排除到某几个类型

用法:

  • 在几个类型中,排除掉一个类型
type MyExclude = Exclude<string | number | boolean, boolean>
//得到的结果  
type MyExclude = string | number

//排除掉多个类型

type MyExclude = Exclude<string | number | boolean, boolean | number>
type MyExclude = string

实现方法:

type Exclude<T,K> = T extends K ? never : T

2.Extract

  • Extract,多个属性中 抽离某一个或者某几个属性,跟Exclude是反着来的
    用法:
type MyExtract = Extract<string | number | boolean, boolean>
type MyExtract = boolean

实现方法:

type Extract<T, K> = T extends K ? T : never;

3.NonNullable

  • NonNullable:在多个类型中排除null类型
    用法:
type MyNonNullable = NonNullable<string | number | null | undefined>

实现方法:

type NonNullable<T> = T extends null | undefined ? never : T;

4.infer推断

  • 需求:获取函数的返回值,infer放在那里,就是推断那里的结果
  • infer 要配合extends关键字,否则无法使用 infer有推断类型的功能,可以自动推断出结果
    需求1:获取函数的返回值的类型
function getSchool(x: string, y: number) {
    return { name: 'zf', age: 12 }
}
  • 使用ReturnType内置条件,得到返回
type MyReturnType = ReturnType<typeof getSchool>
//得到的返回值如下
type MyReturnType = {
    name: string;
    age: number;
}

● 实现原理

type ReturnType<T extends ((...args: any[]) => any)> = T extends ((...args: any[]) => infer R) ? R : any

需求2:获取到函数参数返回的类型

type MyConstructorParameters = ConstructorParameters<typeof Person>
type MyParameters = [x: string, y: number]
  • 实现原理
type Parameters<T extends ((...args: any[]) => any)> = T extends (...args: infer P) => any ? P : any

ts中的内置类型

  • 下面用到的通用例子
interface ICompany {
    name: string,
    address: string
}
interface IPerson {
    name?: string,
    age: number,
    company?: ICompany
}

1.Partial

  • 当我们一个接口中,不确定那些是必填的东西,想要全部改为非必填
  • Partial:表示选项可以是选填的 ,默认不是深度递归
type MyPerson = Partial<IPerson>
 //调用后得到如下结果,把所有选项都标识成了非必填项
type MyPerson = {
    name?: string | undefined;
    age?: number | undefined;
    company?: ICompany | undefined;
}
  • 实现原理
type Partial<T> = [K in keyof T]? : T[K]
  • 但是在我们写company的时候发现,company里面的东西还都是必填的,我们没办法深层递归,所以改写一下上面的写法,利用循环递归改成深度递归
type Partial<T> = { [K in keyof T]?: T[K] extends object ? Partial<T[K]>:T[K] }

2.Required

  • 跟Partial相反,就是把所有的可选的,全部改为必填的
type MyRequired = Required<MyPerson>
//得到如下结果
type MyRequired = {
    name: string;
    age: number;
    company: ICompany;
}
  • 实现原理,值得注意就是 -?,就是去掉?标识
type Required<T> = { [K in keyof T]-?: T[K] }

3.Readonly

  • 标识只读的属性
type MyReadonly = Readonly<IPerson>
//相当于多添加了readonly属性
type MyReadonly = {
    readonly name?: string | undefined;
    readonly age: number;
    readonly company?: ICompany | undefined;
} 
  • 实现原理
type Readonly<T> = { readonly [K in keyof T]: T[K] }

4.Pick

  • Pick 精挑细选 (对象里选属性) extract 抽离可用的 (类型中选择类型
type MyPick = Pick<IPerson, 'age' | 'company'>
//得到如下类型
type MyPick = {
    age: number;
    company?: ICompany | undefined;
}
  • 实现方法
type Pick<T, K extends keyof T> = { [X in K]: T[X] }

5.Omit

  • 忽略属性 两个对象的合并 T & K
type MyType = Omit<IPerson, 'name'> & { name: string };
//得到如下
type MyType = Omit<IPerson, "name"> & {
    name: string;
}
  • 实现方法
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值