当前位置:网站首页>TS 体操 &(交叉运算) 和 接口的继承的区别
TS 体操 &(交叉运算) 和 接口的继承的区别
2022-07-06 07:23:00 【Jioho_】
TS 体操 &(交叉运算) 和 接口的继承的区别
交叉类型 和 接口继承都有合并 2 个对象的作用,可是实际使用起来还是有非常多需要注意的地方
& 交叉类型
& 也称为 交叉类型(Intersection types),先通过 demo 了解一下
type Todo1 = {
name: string
}
type Todo2 = {
description: string
}
type Todo = Todo1 & Todo2
在以上的 demo 中
类型推导显示:type Todo = Todo1 & Todo2
实际效果:type Todo = { name:string; description: string }
情况 2
type NumberAndString = string & number // never
type Todo1 = {
id: string
title: string
do(title: string, status: boolean): void
fn(): void
}
type Todo2 = {
id: number
title: string | number
do(title: string, id: number, status: boolean): void
fn(): void
}
type Todo = Todo1 & Todo2
let todo: Todo = {
id: 'string', // 报错 Type 'string' is not assignable to type 'never'.
id: 1234, // 报错 Type 'number' is not assignable to type 'never'.
title: 'title' // 只能合并为string类型
do(title:string,status:boolean){
},
fn(){
}
}
NumberAndString 的类型推导结果是 never,因为不存在一个值既是 string 又是 number 的。
而 Todo 类型推导结果也一样,id 等于任何值都不对(因为是 never)。对于title 来说 string & string | number 的时候,其实还是 string
do 因为是函数类型,就算参数不一样也无法合并(使用的时候会报错),而 fn 因为函数相同,自然可以合并
得出个结论
- & 交叉类型算的是 2 个类型的 并集。就是双方都有的东西才能合并到一起,不一样的将会被排除
- 如果排除到最后都没有相同的东西,那么就会变 never 类型(即该类型不存在)
- 内置类型(string,number,boolean,unio 联合类型)之间可以使用 &
interface(接口) 的继承
接口的继承与 交叉类型最大的一个区别就是
交叉类型可以在 自定义 type、原始类型(string,number,boolean…) 、联合类型(string | number)、甚至是接口 中相互交叉
接口交叉也遵循 & 的规则,像下面的 demo,id 依旧是交叉为 never 类型
interface ITodo {
id: string
title: string
do(title: string, status: boolean): void
fn(): void
}
interface ITodo2 = {
id: number
title: string | number
do(title: string, id: number, status: boolean): void
fn(): void
}
type Todo = ITodo & ITodo2
var todo: Todo = {
id: 1, // 报错
title: '',
do() {
} // 报错
fn(){
}
}
而继承只能从一个接口继承另外一个接口的内容
接口继承的时候,如果遇到同一键名但是值不符的,那么继承的时候就会报错,而不是合并为 never
包括方法的名称,哪怕继承过来后想重写,参数也必须和继承前保持一致
使用 type 还是使用 interface 的终极问题
type 和 interface 都是为了定义类型,约束变量。并且都支持拓展自己的字段
在继承/拓展字段的层面上
在日常使用中,type 可以用 & 运算符进行 2 个 type 的合并,合并过程中有 “冲突” 的字段会自动被合并为 never (在定义 type 的时候并没有感觉到这个字段会 never)
而 inteface 采用的则是 “继承”,在继承过程中,如果有冲突,那么在定义接口的时候就会立刻感知到
在定义类型的层面上
type 可以很方便的就组合基础类型,形成一个新的类型,比如
// 定义一个时间戳字段,时间戳可能是字符串,也可以是数字
type TimeStamp = string | number | bigInt
var time: TimeStamp = new Date().getTime()
而接口类型,则必须定义一个完整的接口。对于单个字段的限制,type 是略胜一筹
说到最后,估计也没有一个标准说明什么情况该用什么来定义类型。
如果开发的内容可能是一个 base 模块,很多地方都需要继承这个 base 进行开发,那推荐 interface。因为这很接口,而且当别人继承过去后新增/修改字段的时候会立刻知道,噢,原来这个字段 base 模块定义了,我这样改会冲突
而 type 类型也能定义,我个人感觉更多的是定义一些不需要对外的东西,或者不会经常被拿去继承后修改的东西
比如 TS 体操,看到的工具类基本都是 type 定义的,因为 type 既可以返回 {} 也能返回单个字段。开发工具类的时候最多也是 相互引用,没听说过 把 Pick 工具类继承过来加点功能 这样的话把。 type 用来定义工具类,定义单个字段,是非常合适的,定义对象也 OK(就是继承的时候没接口灵活)各有特点
所以到底选中 type / interface,还是看业务场景和代码编写的经验积累。当你写多了,一眼就能看出,这个用 xxx 是最合适的
最后
总结一下子
- & 符用于合并 2 个/多个类型的 “交集”,当交集有冲突的时候则会自动转换为 never
- & 对 type 和 interface 都能生效,对这 2 个定义都能合并
- extend 只能从一个接口继承另外一个接口的内容
- extend 接口继承的时候如果类型的 “交集” 有冲突,那么定义接口的时候就会有提示(报错),不会自动转换为 never
既然说到 type 和 interface,最后感觉基于上面类型合并的思考可以很顺利的引出什么场景适合用 type 还是用 interface
定义单个字段的时候/定义工具类(做类型体操)的时候 type 非常合适
定义 base 类/模块需要对外提供功能,提供接口/模块会被其他模块继承过去拓展的时候,interface 自然是当仁不让
边栏推荐
- leecode-C語言實現-15. 三數之和------思路待改進版
- chrome查看页面fps
- Ble of Jerry [chapter]
- Select all the lines with a symbol in word and change them to titles
- word删除括号里内容
- Leetcode35. search the insertion position (simple, find the insertion position, different writing methods)
- OpenJudge NOI 2.1 1749:数字方格
- The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
- 2022年Instagram运营小技巧简单讲解
- Ble of Jerry [chapter]
猜你喜欢

CDN acceleration and cracking anti-theft chain function
![Jerry's ad series MIDI function description [chapter]](/img/28/e0f9b41db597ff3288af431c677001.png)
Jerry's ad series MIDI function description [chapter]

Idea console color log

Internal and external troubles of "boring ape" bayc

navicat如何导入MySQL脚本

【mysql学习笔记30】锁(非教程)

Relevant introduction of clip image

The way to learn go (I) the basic introduction of go to the first HelloWorld

数字IC设计笔试题汇总(一)

C - Inheritance - polymorphism - virtual function member (lower)
随机推荐
TypeScript void 基础类型
On the world of NDK (2)
ORACLE列转行--某字段按指定分隔符转多行
Typescript variable scope
Redis builds clusters
[online problem processing] how to kill the corresponding process when the MySQL table deadlock is caused by the code
Openjudge noi 2.1 1749: Digital Square
jmeter性能测试步骤实战教程
Simple and understandable high-precision addition in C language
Brief explanation of instagram operation tips in 2022
Yield method of tread
Leetcode 78: subset
Oracle column to row -- a field is converted to multiple rows according to the specified separator
Sélectionnez toutes les lignes avec un symbole dans Word et changez - les en titre
GET/POST/PUT/PATCH/DELETE含义
[MySQL learning notes 32] mvcc
Wechat official account infinite callback authorization system source code, launched in the whole network
Path analysis model
MVVM of WPF
Scala language learning-08-abstract classes