typescript高级类型-类型兼容性

类型兼容性

在 TypeScript 中,对象类型兼容性是指当一个对象赋值给另一个对象时,是否满足类型要求。TypeScript 的类型兼容性是基于结构子类型而不是名义类型的,这意味着只要源类型的属性和方法满足目标类型的要求,就认为两个类型是兼容的。

TypeScript 的对象类型兼容性规则如下:

  1. 源类型必须具有目标类型中的所有必需属性。
  2. 源类型的可选属性必须在目标类型中也存在,并且类型匹配。
  3. 源类型不能有目标类型中不存在的属性。
  4. 目标类型可以有额外的属性,但是源类型的属性必须是目标类型属性的子集。

两种类型系统:1StructuralType System (结构化类型系统)2 NominalType System (标明类型系统)。
TS 采用的是结构化类型系统,也叫做 ducktyping (鸭子类型…?什么???你不明白什么叫鸭子类型? 伟大的鲁迅先生说过如果一个东西,看起来是鸭子,叫起来像鸭子,吃起来像鸭子,那它就是鸭子!!!),
类型检查关注的是值所具有的形状。
也就是说,在结构类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型。

class Point  x: number; y: number
class Point2D { x: number; y: number
const p: Pointt= new Point2DC

解释:

  1. Point和Point2D是两个名称不同的类
  2. 变量p的类型被显示标注为Point类型,但是,它的值却是Point2D 的实例,并且没有类型错误。
  3. 因为TS 是结构化类型系统,只检查Point和 oint2D 的结构是否相同(相同,都具有和y 两个属性,属性类型也相同)。
  4. 但是,如果在NominalType System 中(比如,C#、Java等),它们是不同的类,类型无法兼容。

对象间的兼容性

tips
:在结构化类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型,这种说法并不准确。
更准确的说法: 对于对象类型来说,y 的成员至少与相同,则X 兼容y(成员多的可以赋值给少的)。

class Point  x: number; y: number
class Point3D [ x: number; y: number; z: numberconst p: 
Point = new Point3()

解释:
Point3D的成员至少与Point相同,则Point兼容Point3D
2.所以,成员多的Point3D可以赋值给成员少的Point。

接口之间的兼容性

除了class 之外,TS中的其他类型也存在相互兼容的情况,包括:1接口兼容性2函数兼容性等接口之间的兼容性,类似于 class。并且,class和 interface 之间也可以兼容。

//声明一个拥有两个number成员接口Point
interface Point { x: number; y: number }
//声明一个拥有两个number成员接口Point2D
interface Point2D { x: number; y: number }// 声明一个变量p1,类型为Point 
let p1: Point = { x: 10, y: 20 };
//声明一个变量p2 类型为ponit2D,并将p1赋值给它
// 可以看到并没有报错
// 因为接口也拥有兼容性,只要结构一致
let p2: Point2D = p1//再声明一个拥xyz有三个number成员接口的Point3D
interface Point3D { x: number; y: number; z: number }
//声明一个Point3D类型变量p3
let p3: Point3D = { x: 10, y: 20, z: 30 }
//将p3赋值给p2
p2 = p3// 再声明一个Point3D类
class Point3D { x: number; y: number; z: number }//声明一个Point2D类型变量p4,将Point3D实例赋值给它
// 可以看到也没有报错
let c3: Point2D = new Point3D()

函数之间的兼容性

函数之间兼容性比较复杂,需要考虑:

  1. 参数个数
  2. 参数类型
  3. 返回值类型

参数个数 参数多的兼容参数少的(或者说,参数少的可以赋值给多的) 示例如下

// 定义一个名为 "F1" 的函数类型:没有返回值,只有一个number参数
type F1 = (a: number) => void
// 定义一个名为 "F2" 的函数类型:没有返回值,只有两个number参数
type F2 = (a: number, b: number) => void;
// 声明变量f1:类型注解为F1并初始化
let f1: F1 = (a: number) => { }
//声明一个变量f2:类型注解为f2,再将f1赋值给f2
// 可以看到并没有报错
let f2: F2 = f1// 声明一个数组arr
const arr = ['a', 'b', 'c']
// 调用数组的foreach函数并传入一个无参箭头函数
arr.forEach(() => { })
// 调用数组的foreach函数并传入一个一个参数的箭头函数
// 可以看到因为函数的类型兼容性,多个参数的函数能兼容参数少的函数
// 所以这里没有报错
arr.forEach(x => { }) 
  1. 参数少的可以赋值给参数多的,所以,f1 可以赋值给f2。
  2. 数组 forEach 方法的第一个参数是回调函数,该示例中类型为: (value:string,index: number, array: stringl)=>void.
  3. 在J5中省略用不到的函数参数实际上是很常见的,这样的使用方式,促成了T5中函数类型之间的兼容性
  4. 并且因为回调函数是有类型的,所以,TS会自动推导出参数item、index、array的类型。

参数类型 相同位置的参数类型要相同(原始类型)或兼容(对象类型)

如下我们可以看到,当我们将拥有不同参数类型的f1赋值给f3时报错了

在这里插入图片描述

解释:函数类型F2兼容函数类型F1,因为F1和F2的第一个参数类型相同。

返回值类型** 只关注返回值类型本身即可**

如果返回值类型是原始类型,此时两个类型要相同,比如,左侧类型F5 和 F6。
如果返回值类型是对象类型,此时成员多的可以赋值给成员少的,比如,右侧类型F7 和 F8。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/691256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIP---OSPF

题目: 一:IP规划并配置 全网拿192.16.0.0/16划分,先按区域划分,一共有五个区域加上一共RIP网段,要借三位。 255.255. 11100000.00000000 172.16. 00000000.00000000 172.16.0.0/19 区域0 172.16. 00100000.00…

Vue中$root的使用方法

查看本专栏目录 关于作者 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas&#x…

面试redis篇-03缓存击穿

原理 缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮 解决方案一:互斥锁 解决方案二:逻辑过期 提问与回答 面试官 :什么是缓存击穿 ? 怎么解决 ? 回答: 缓存击穿的意思…

【Linux】主机搭建 Linux服务器环境 笔记

目录 前言选择系统软件1. 用U盘装系统2. 安装 Centos7.93. 网络套件 应用软件1. ngnix2. 防火墙配置3. nodejs 后记 前言 过年买了个 mini 主机当玩具玩一下,这里记录下。 选择 已有主力机 (windows) 的情况下,使用过如下四种 Linux宿主环境。这里总…

【C语言必刷题】4. 打印100~200之间的素数

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…

Linux调优指南

更多相关知识可以阅读: https://www.yuque.com/treblez/qksu6c/yxl59pkvczqot9us https://www.yuque.com/treblez/qksu6c/nqe8ip59cwegl6rk 本文不会讲解基础知识。 CPU 设置调度器 这几个调度类的优先级如下:Deadline > Realtime > Fair 如果你…

频谱仿真平台HTZ Communications为私有5G建设铺平道路

韩国的国家监管机构韩国通信委员会(KCA)计划在德思特频谱仿真平台HTZ Communications的支持下加快扩大无线电接入范围,提升全国电信服务的质量和效率。 韩国通信委员会(KCA)在韩国的监管环境中扮演着至关重要的角色&am…

《C++ Primer Plus》《5、循环和关系表达式》

文章目录 1 for循环1.1for循环的组成部分1.2回到for循环1.3修改步长1.4使用for循环访问字符串1.5递增运算符和递减运算符1.6副作用和顺序点(了解)1.7前缀格式和后缀格式1.8递增/递减运算符和指针1.9组合赋值运算符1.10复合语句(语句块&#x…

设计模式: 建造者模式

文章目录 一、什么是建造者模式二、建造者模式的结构三、使用场景案例分析1、使用场景2、案例分析 一、什么是建造者模式 建造模式通过一步一步的去构建一个复杂的对象。该模式将对象的构建细节封装在一个独立的建造者类中,使得客户端代码可以根据需要定制对象的构…

cRIO9040中NI9381模块的测试

硬件准备 CompactRIO9040NI9381直流电源(可调)网线 软件安装 下载地址 LabVIEW Real-Time 模块 NI CompactRIO 设备驱动程序 LabVIEW FPGA 模块(可选) 仅以下情况需要LabVIEW FPGA模块: 想为CompactRIO终端设计FP…

Gitlab操作流程

阶段1-构建账户信息 1.1 管理员分配账户 方式1-推荐 企业正常使用gitlab时,一般由项目经理(超级管理员)手动创建开发者账户信息,然后将账户发送给开发者,以便登录使用; 流程如下: 点击创建用户按钮; 创…

顶顶通实时质检系统如何添加词库

文章目录 前言联系我们步骤1. 导入系统预置词库2. 手动添加词库 在实时质检时如何质检到词库 前言 本篇文章主要讲解顶顶通实时质检系统如何添加词库。 词库添加的方式: 导入系统预置词库手动添加词库 联系我们 有意向了解实时质检系统的用户,可以点击…

web基础及http协议 (二) apache

一、httpd 安装组成 http 服务基于 C/S 结构 1 .常见http 服务器程序 httpd apache,存在C10K(10K connections)问题 nginx 解决C10K问题lighttpd IIS .asp 应用程序服务器 tomcat .jsp 应用程序服务器 jetty 开源的servlet容器&#xf…

10款ai文生图软件/网站推荐

1. Ai-Chat 推荐指数:⭐⭐⭐⭐ 链接: https://mmm.aiyujiang.com/ 上传图片并输入AI提示词就能一键生成各类动漫、卡通风格头像,算法强大,风格多样,一键开启你的AI自由创作之旅。有电脑版和手机版,也是很…

大数据信用报告查询方式一般有几种?哪种比较好?

在了解这个问题之前,想必你对大数据信用与人行信用的区别都是比较清楚了,本文呢就着重讲一下大数据信用报告查询方式有几种,哪种比较好,感兴趣的朋友不妨一起去看看。 大数据信用报告常见的三种查询方式: 一、二维码分…

手持三防平板丨国产化加固平板丨国产三防平板发展的意义是什么?

随着现代科技的快速发展,平板电脑在我们的生活中扮演着越来越重要的角色。然而,传统的平板电脑只能在普通的环境中使用,而无法在恶劣的环境中使用,例如在高海拔、高温、高湿度、沙漠等环境中,传统平板电脑往往会出现故…

图的遍历(广度优先遍历BFS,深度优先遍历DFS)

目录 图的遍历概念: 图的广度优先遍历(BFS): 代码实现如下: 测试如下: 注意: 图的深度优先遍历(DFS): 代码实现如下: 测试如下&#xff1…

Web服务器基础

Web服务器基础 【一】前端概述 【1】HTML HTML(超文本标记语言)是用于创建网页结构的标记语言。它定义了网页的骨架,包括标题、段落、列表、链接等元素,但没有样式。可以将HTML视为网页的结构和内容的描述。 【2】CSS css&…

阿里云服务器镜像是什么?如何选择镜像?

阿里云服务器镜像怎么选择?云服务器操作系统镜像分为Linux和Windows两大类,Linux可以选择Alibaba Cloud Linux,Windows可以选择Windows Server 2022数据中心版64位中文版,阿里云服务器网aliyunfuwuqi.com来详细说下阿里云服务器操…

Go 是否有三元运算符?Rust 和 Python 是怎么做的?

嗨,大家好!本文是系列文章 Go 技巧第十四篇,系列文章查看:Go 语言技巧。 今天来聊聊在 Go 语言中是否支持三元运算符。这个问题很简单,没有。 首先,什么是三元运算符? 在其他一些编程语言中&a…