困惑

初学 ts 时,extends 让我很困惑:有时它代表 扩大 ,有时代表 缩小 。举几个例子说明:

例1:
class Animal {}
class Dog extends Animal {}

这是 js 本身就有的 class 继承语法,很熟悉了。
Dog 是 Animal 的子类,是对 Animal 的扩展,可以比 Animal 有更多的属性和方法。
extends 似乎代表 扩大

例2:
type MyPick<T, K extends keyof T> = {[P in K]: T[P];
};

K extends keyof T 的含义是“K 是 keyof T 的子集”。K 的取值被限制在 keyof T 内,可以少,不能多。
extends 似乎代表 缩小

例3:
function longest<T extends { length: number }>(a: T, b: T) {return a.length >= b.length ? a : b;
}

T extends { length: number } 要求 T 必须有 length 属性,这样在函数体中才可以直接使用 a.length 和 b.length。
T 除了 length,还可以有其他属性和方法。
extends 似乎代表 扩大


解释

说扩大或者缩小其实含义很模糊,没有实际意义。因为没有明确主语:具体是什么扩大/缩小了。

ts 中的 extends 应该用 子类型(assignable) 去理解。

子类型:如果在期望类型 T 的实例的任何地方,都可以安全地使用类型 S 的实例,那么称类型 S 是类型 T 的子类型。

如果我们能够把任何值赋给类型 T,那么称 T 为顶层类型。其他任何类型都是 T 的子类型。ts 中的顶层类型是 unknown,java 中的顶层类型是 Object

如果类型 T 是其他任何类型的子类型,那么称 T 为底层类型。ts 中的底层类型是 never,是不能被赋值的空类型。可以类比集论中的概念:空集是任何集合的子集。

大白话总结:unknown 是终极父类,never 是终极子类。

所以,子类型 extends 父类型,至于是扩大还是缩小要看考虑问题的角度。用上面的例1说明:

class Animal {}
class Dog extends Animal {}
  • Dog 比 Animal 有更多的属性和方法。这个角度看,Dog 是对 Animal 的扩展。
  • Dog 对 Animal 加了限制,所以 Dog 能取的值比 Animal 要少:Dog 一定是 Animal,但 Animal 不一定是 Dog。这个角度看,Dog 是对 Animal 的缩小

大白话总结:子类特性多了,可取值少了。


引申

前提 Dog extends Animal,考虑下面几种类型的关系:

  • Dog[]Animal[] 的关系
  • () => Dog() => Animal 的关系
  • (arg:Dog) => void(arg:Animal) => void 关系

答案:

  • Dog[]Animal[] 的子类型
  • () => Dog() => Animal 的子类型
  • (arg:Animal) => void(arg:Dog) => void 的子类型。注意这里反过来了。稍微有点绕,用 assignable 的思路去考虑

另外,ts 中强行规定了 (arg:Dog) => void 也是 (arg:Animal) => void 的子类型。这样是不安全的,运行时可能出错。但是 ts “为了方便实现常见的js编程模式“,就是这样设计了。


最后说一说 ts 中的 any。虽然 any 和 unknown 常被放在一起讨论,但其实性质完全不同。在 ts 中,unknownnever 都是正规的类型体系的一部分。但 any 完全在这个体系之外:

ts 中,所有值都可以赋给 any 类型,any 类型的值也可以赋值给其他任何类型,从而绕过类型检查。

写代码时如果用了 any 类型,就代表着:我完全知道我在做什么,这一部分代码的安全与正确性我自己负责。ts 请无视这段代码,不要进行任何类型检查。

extends in typescript相关推荐

  1. TypeScript 里 interface 和 type 的区别

    StackOverflow 上的讨论链接 Interface vs Type alias in TypeScript 2.7 Differences Between Type Aliases and ...

  2. TypeScript内置对象

    前言 JavaScript 中有很多内置对象,它们可以直接在 TypeScript 中当做定义好了的类型. 内置对象是指根据标准在全局作用域(Global)上存在的对象.这里的标准是指 ECMAScr ...

  3. 从0到1落地前端代码检测工具

    点击上方 前端Q,关注公众号 回复加群,加入前端Q技术交流群 中大型公司中前端项目往往不止一个,前端开发人员多加上前端项目众多,为了维持一定的项目团队风格往往十分艰难.这篇文章主要是在公司中针对组内现 ...

  4. 【工程化】1202- 从0到1落地前端代码检测工具

    相关背景: 中大型公司中前端项目往往不止一个,前端开发人员多加上前端项目众多,为了维持一定的项目团队风格往往十分艰难.这篇文章主要是在公司中针对组内现状问题进行问题收集.调研.开发.落地的总结. 1. ...

  5. 【Web技术】1179- 从0到1落地前端代码检测工具

    相关背景: 中大型公司中前端项目往往不止一个,前端开发人员多加上前端项目众多,为了维持一定的项目团队风格往往十分艰难.这篇文章主要是在公司中针对组内现状问题进行问题收集.调研.开发.落地的总结. 1. ...

  6. 手摸手带学妹从0到1落地前端代码检测工具

    点击上方"蓝色字体",选择"设为星标" 做积极向上的前端人! 相关背景: 中大型公司中前端项目往往不止一个,前端开发人员多加上前端项目众多,为了维持一定的项目团 ...

  7. TypeScript 基础学习之泛型和 extends 关键字

    越来越多的团队开始使用 TS 写工程项目, TS 的优缺点也不在此赘述,相信大家都听的很多了.平时对 TS 说了解,仔细思考了解的也不深,借机重新看了 TS 文档,边学习边分享,提升对 TS 的认知的 ...

  8. Typescript中class的extends码源分析

    学习typescript的乐趣在于看它的码源是如何要js实现的. 今天要分析的是类继承的码源.我们先来看一下使用ES5的组合继承是如何做到的: 1 function Person(name) { 2 ...

  9. Typescript中的extends关键字

    前言 extends关键字在TS编程中出现的频率挺高的,而且不同场景下代表的含义不一样,特此总结一下: 表示继承/拓展的含义 表示约束的含义 表示分配的含义 基本使用 extends是 ts 里一个很 ...

最新文章

  1. R语言ggplot2可视化抑制(部分)图例(legend)输出实战:抑制颜色图例输出、保留数据点形状图例输出
  2. html多列显示,html – CSS3多列列表
  3. socket 获取回传信息_基于netty框架的socket长连接负载均衡解决方案 oswl
  4. BZOJ2525 [Poi2011]Dynamite 【二分 + 贪心】
  5. Shell 编程快速入门
  6. VMware View 4.0 测试-7
  7. 算法——动态规划算法求解字符串的编辑距离
  8. 终端服务器超出最大允许连接数
  9. xp系统下如何安装windows phone 7的软件xap文件
  10. 智慧树工业机器人测试答案_智慧树_工业机器人技术基础_答案章节单元测试答案...
  11. php 生成导出excel,PHP导出生成EXCEL文件
  12. failed to create the npcap service 0x8007007e
  13. Python——click模块
  14. 利用Java实现将华氏温度转换为摄氏温度
  15. 13. nginx四层 https代理https 前后端证书配置
  16. C语言 | C语言深度解剖 ——章节2 符号
  17. 【产品人生】<基础认知>产品分析方法产品体验分析报告撰写
  18. 网易杭研易盾实习心得
  19. android 在线预览pdf文件
  20. git pull 报错 Your local changes would be overwritten by merge. Commit, stash or revert them to procee

热门文章

  1. js如何获取jwt信息_如何获取有价值的信息
  2. CnOpenData中国绿色专利分地区统计数据
  3. ECharts系列 - 柱状图(条形图)实例一
  4. dell灵越7370 U盘装机 BIOS设置
  5. 智慧养老解决方案-智慧养老具体方案之一-新导智能
  6. 常见的几种清除浮动(高度塌陷)的方法?
  7. 世界大学排名(前100名)一览表
  8. 论述word加密与破解的“矛”与“盾”!
  9. 多索引、多类型查询:
  10. 关于实行专业技术职务聘任制度的规定