当前位置:首页 > 科技  > 软件

TypeScript 中的 Extends 怎么那么优秀啊?

来源: 责编: 时间:2024-05-07 09:11:49 95观看
导读在学习和使用 ts 的时候,有一个语法会大量的出现,他就是 extends。但是这个语法放到 ts 里,就显得非常怪异,因为好多时候跟我们常规的理解看上去好像不太一样,不就是一个继承吗,咋到处都在乱用啊?实际上,之所以怪,是因为在 ts

dkc28资讯网——每日最新资讯28at.com

在学习和使用 ts 的时候,有一个语法会大量的出现,他就是 extends。但是这个语法放到 ts 里,就显得非常怪异,因为好多时候跟我们常规的理解看上去好像不太一样,不就是一个继承吗,咋到处都在乱用啊?dkc28资讯网——每日最新资讯28at.com

实际上,之所以怪,是因为在 ts 中,extends 不只是要表达继承的意思,他还有一些延展含义。dkc28资讯网——每日最新资讯28at.com

在 JS 核心进阶中,我们在学习设计模式的时候,曾经提高过一个原则:里氏替换原则,该原则针对的是父类与子类之间的替换关系:任何使用父类实例的地方,都能够使用子类实例完美替换。dkc28资讯网——每日最新资讯28at.com

class Person {  constructor(name) {    this.name = name  }  run(t) {    console.log(`${this.name} 跑了 ${t} 公里`);  }}class Student extends Person {  constructor(name, grade) {    super(name)    this.grade = grade  }}const p1 = new Person('Tom')p1.run(20)const s1 = new Student('Tom')s1.run(20)

这个案例中,我们能够使用 s1 去替换 p1。而不会出现什么问题。dkc28资讯网——每日最新资讯28at.com

在 ts 的类型兼容性里,也符合这个原则。基于这个逻辑,我们就可以把 extends 作为一个判断条件,来验证你是否合理运用了里氏替换原则,从而衍生出它新的用法。dkc28资讯网——每日最新资讯28at.com

一、继承

继承的运用非常的常规。在面向对象的运用中,我们可以继承一个父类。dkc28资讯网——每日最新资讯28at.com

class Parent {}class Children extends Parent {}

我们也可以在 interface 的类型声明中,使用继承。dkc28资讯网——每日最新资讯28at.com

interface Animal {  kind: string}interface Dog extends Animal {  bark(): void}

它等价于。dkc28资讯网——每日最新资讯28at.com

interface Dog {  kind: string  bark(): void}

二、泛型约束

我们先简单来看一下这个东西是如何在泛型中使用的,然后再来结合里氏替换原则来分析它的逻辑。dkc28资讯网——每日最新资讯28at.com

interface Dispatch<T extends { type: string }> {  (action: T): T}

我们在定义 Dispatch 时需要传入一个泛型,传入的泛型类型必须与 {type: string} 符合里氏替换原则。意思就是说,要传入该类型的子类型。dkc28资讯网——每日最新资讯28at.com

因此,我们可以传入。dkc28资讯网——每日最新资讯28at.com

var action = {  type: 'get/list',  playload: 10}

也可以传入。dkc28资讯网——每日最新资讯28at.com

var action = {  type: 'merge'}
var action = {  type: 'add',  value: { a: 1, b: 2 }}

从结论上来看,父类型的约束力度更小,子类型的约束力度更大。dkc28资讯网——每日最新资讯28at.com

三、条件判断

我们可以可以继续衍生,当子类型与父类型符合正常的继承关系时,判断结果为 true,否则为 false。dkc28资讯网——每日最新资讯28at.com

这里的继承关系,表达的是一种替换关系,或者说是约束力度的缩小。dkc28资讯网——每日最新资讯28at.com

type C = A extends B ? string : number

这里表达的含义是,当 A 能够替换 B 时,判断结果为 true,否则,判断结果为 false。dkc28资讯网——每日最新资讯28at.com

interface Person {  name: string}interface Yung extends Person {  gender: string}interface Student extends Yung {  age: string}

也就是说,当 A 作为 B 的子类型时,判断结果为 true。dkc28资讯网——每日最新资讯28at.com

// 此时判断结果为truetype C = Yung extends Person ? number : string // number
// 此时判断结果为falsetype C = Yung extends Student ? number : string // string

也可以结合泛型使用。dkc28资讯网——每日最新资讯28at.com

type P<T> = T extends string ? string : numbertype Z = P<string> // string

当我们在使用泛型的时候,会出现一些问题,看一下这个例子。dkc28资讯网——每日最新资讯28at.com

type A = number | string extends string ? string : number // number

因为 string 的约束力度,比 number | string 更大,因此这里的条件判断为 false,但是当我们通过泛型来做到同样的事情时,情况就发生了变化。dkc28资讯网——每日最新资讯28at.com

type P<T> = T extends string ? string : numbertype A = P<number | string> // string | number

当我们用泛型传递时候,跟预想中的不太一样,这里会把泛型传入的 number 和 string 拆分之后在去运行 extends 判断。因此最后的结果是 string | number。dkc28资讯网——每日最新资讯28at.com

联合类型在泛型中的表现是分配之后再传入。dkc28资讯网——每日最新资讯28at.com

在实践中一定要警惕这个小小的差异。我们可以使用如下的方式避免这种先分配再传入的规则。dkc28资讯网——每日最新资讯28at.com

type P<T> = [T] extends [string] ? string : numbertype A = P<number | string> // number

never 表示所有类型的子类型,因此也被看成是一个联合类型,当我们在泛型中传入 never 时也会同理出现同样的问题。dkc28资讯网——每日最新资讯28at.com

type P<T> = T extends string ? string : number// 没有类型可分配,直接返回 nevertype A = P<never> // never

注意他们的不同。dkc28资讯网——每日最新资讯28at.com

type P<T> = [T] extends [string] ? string : numbertype A = P<never> // string

四、定义一个 pick

现有一个对象 A 有很多个属性,我希望重新定义一个新的对象 B,该对象的属性是从 A 里挑选出来的,那么 B 的类型应该怎么定义呢。dkc28资讯网——每日最新资讯28at.com

interface A {  name: string;  age: number;  gender: number;  class: string}

当然,我们可以用常规的方式来定义,不过有的时候这样会比较麻烦。dkc28资讯网——每日最新资讯28at.com

interface B {  name: string,  age: number}

我们也可以利用泛型和 extends,定义一个 Pick 类型。dkc28资讯网——每日最新资讯28at.com

type Pick<T, K extends keyof T> = {  [P in K]: T[P]}type B = Pick<A, 'name' | 'age'>

当我们在 Pick 中传入 A 时, keyof A 的结果为 name | age | gender | class,因此 'name' | 'age' 是 keyof A 的子类型。dkc28资讯网——每日最新资讯28at.com

此时的 B 得到与上面写法一样的结果。dkc28资讯网——每日最新资讯28at.com

五、定义一个 Exclude

现在我有一个联合类型。dkc28资讯网——每日最新资讯28at.com

type a = 'name' | 'age' | 'gender' | 'class'

我希望排除其中一个 name,得到一个新的联合类型。dkc28资讯网——每日最新资讯28at.com

type b = 'age' | 'gender' | 'class'

此时我们可以定一个排除的泛型类型来做到这个事情。dkc28资讯网——每日最新资讯28at.com

type b = Exclude<a, 'name'>

这个 Exclude 是如何实现的呢?非常的简单。dkc28资讯网——每日最新资讯28at.com

type Exclude<T, U> = T extends U ? never : Ttype b = Exclude<a, 'name'>

我们来分析一下,首先刚才我们已经知道,当传入的泛型为联合类型时,会先分配再传入。dkc28资讯网——每日最新资讯28at.com

因此,此时传入的联合类型 a 会被拆分传入。dkc28资讯网——每日最新资讯28at.com

也就是说,T exnteds U 的比较会变成。dkc28资讯网——每日最新资讯28at.com

// never'name' extends 'name' ? never : 'name'// age'age' extends 'name' ? never : 'age'// gender'gender' extends 'name' ? never : 'gender'// class'class' extends 'name' ? never : 'class'

所以通过这种方式,我们可以做到从联合类型中排除指定的类型。dkc28资讯网——每日最新资讯28at.com

六、定义一个 Omit

Omit 是 Pick 的取反,表示挑选剩余的属性组成新的对象。理解了 Pick 和 Exclude,这个理解起来非常容易。dkc28资讯网——每日最新资讯28at.com

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

使用:dkc28资讯网——每日最新资讯28at.com

interface A {  name: string,  age: number,  gender: number,  class: string}type B = Omit<A, 'name'>

等价于:dkc28资讯网——每日最新资讯28at.com

interface A {  age: number,  gender: number,  class: string}

大家可以自己分析一下 Omit 的实现原理,应该是没有任何难度的。dkc28资讯网——每日最新资讯28at.com

七、最后

最后来个骚的,大家分析一下这玩意儿有什么用dkc28资讯网——每日最新资讯28at.com

type TypeString<T> =    T extends string ? "string" :    T extends number ? "number" :    T extends boolean ? "boolean" :    T extends undefined ? "undefined" :    T extends Function ? "function" :    "object";

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-87003-0.htmlTypeScript 中的 Extends 怎么那么优秀啊?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 逆向之旅:七个让Python编程更糟糕的小技

下一篇: Fo-dicom,第一个基于.NET Standard 2.0 开发的DICOM开源库

标签:
  • 热门焦点
  • 直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    旗舰机基本上使用的都是双曲面屏幕,这就让很多喜欢直屏的爱好者在苦等一款直屏旗舰,这次,你们等到了。据博主数码闲聊站带来的最新爆料称,Redmi下代旗舰K70 Pro和iQOO 12两款手
  • 影音体验是真的强 简单聊聊iQOO Pad

    影音体验是真的强 简单聊聊iQOO Pad

    大公司的好处就是产品线丰富,非常细分化的东西也能给你做出来,例如早先我们看到了新的vivo Pad2,之后我们又在iQOO Neo8 Pro的发布会上看到了iQOO的首款平板产品iQOO Pad。虽
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 一个注解实现接口幂等,这样才优雅!

    一个注解实现接口幂等,这样才优雅!

    场景码猿慢病云管理系统中其实高并发的场景不是很多,没有必要每个接口都去考虑并发高的场景,比如添加住院患者的这个接口,具体的业务代码就不贴了,业务伪代码如下:图片上述代码有
  • 每天一道面试题-CPU伪共享

    每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • Temu起诉SHEIN,跨境电商战事升级

    Temu起诉SHEIN,跨境电商战事升级

    来源 | 伯虎财经(bohuFN)作者 | 陈平安日前据外媒报道,拼多多旗下跨境电商平台Temu正对竞争对手SHEIN提起新诉讼,诉状称Shein&ldquo;利用市场支配力量强迫服装厂商与之签订独家
  • 超级标准版旗舰!iQOO 11S全球首发iQOO超算独显芯片

    超级标准版旗舰!iQOO 11S全球首发iQOO超算独显芯片

    上半年已接近尾声,截至目前各大品牌旗下的顶级旗舰都已悉数亮相,而下半年即将推出的顶级旗舰已经成为了数码圈爆料的主流,其中就包括全新的iQOO 11S系
  • 7月4日见!iQOO 11S官宣:“鸡血版”骁龙8 Gen2+200W快充加持

    7月4日见!iQOO 11S官宣:“鸡血版”骁龙8 Gen2+200W快充加持

    上半年已接近尾声,截至目前各大品牌旗下的顶级旗舰都已悉数亮相,而下半年即将推出的顶级旗舰已经成为了数码圈爆料的主流,其中就包括全新的iQOO 11S系
  • AI艺术欣赏体验会在上海梅赛德斯奔驰中心音乐俱乐部上演

    AI艺术欣赏体验会在上海梅赛德斯奔驰中心音乐俱乐部上演

    光影交错的镜像世界,虚实幻化的视觉奇观,虚拟偶像与真人共同主持,这些场景都出现在2019世界人工智能大会的舞台上。8月29日至31日,“AI艺术欣赏体验会”在上海
Top
Baidu
map