精进TypeScript--你了解类型(type)和接口(interface)的区别吗?

2024-04-04 08:36

本文主要是介绍精进TypeScript--你了解类型(type)和接口(interface)的区别吗?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

要记住的事情:

  • 理解 type 和 interface 之间的异同
  • 知道如何使用其中一种语法来编写相同的类型
  • 当决定在你的项目中使用哪一种语法时,既要考虑既定的风格,也要考虑扩增是否会有好处

如果你想在 TypeScript 中定义一个命名类型,你有两种选择,使用一个类型或接口,如下:

type TState = {name: string;capital: string;
}interface IState {name: string;capital: string;
}

你应该使用哪个?你应该意识到 type 和 interface 之间的区别,并且在哪种情况下使用哪一种都要保持一致。但是,你也应该知道如何使用这两种方式来编写相同的类型,这样你就能自如地读懂使用这两种编写的 TypeScript 代码。

首先,关于相似性:State 类型之间几乎没有区别。不管你用 IState 还是 TState 定义了一个带有多余属性的值,你得到的错误是字对字相同的:

const state: TState = {name: 'China';capital: 'BeiJing';population: 5000000; // ~~ 不能将类型 ... 分配给类型 “TState”
}

你可以对 interface 和 type 使用索引签名:

type TDict = {[key: string]: string};
interface IDict {[key: string]: string;
}

你也可以用它们中的任意一个定义函数类型:

type TFn = (x: number) => string;
interface IFn {(x: number): string;
}const toStrT: TFn = x => '' + x; // OK
const toStrI: IFn = x => '' + x; // OK

对于这种直接的函数类型,类型别名看起来更自然,但如果函数类型也具有属性,那么声明看起来就更相似。

type TFnWithProperties = {(x: number): number;prop: string;
}
interface IFnWithProperties {(x: number): number;prop: string;
}

你可以通过提醒自己,在JavaScript 中,函数是可调用的对象,来记住这种语法。

类型别名和接口都可以是泛型:

type TPair<T> = {first: T;second: T;
}interface IPair<T> = {first: T;second: T;
}

interface 可以扩展 type,type 也可以扩展 interface:

interface IStateWithPop extends TState {population: number;
}
type TStateWithPop = IState & {population: number;}

同样,这两个类型都是相同的。需要注意的是,interface 不能扩展复杂的类型,如联合类型。如果你想这么做,你需要使用 type 和 &。

类(class)可以实现interface或简单类型:

class StateT implements TState {name: string = '';capital: string = '';
}
class StateI implements IState {name: string = '';capital: string = '';
}

这些是相似之处。那不同之处呢?你已经看到了一个:有联合 type,但没有联合 interface:

type A or B = 'a' | 'b';

扩展联合类型是很有用的。如果你有单独的 Input 和 Output 变量的类型,以及从名字(name)到变量的映射:

type Input = { /*...*/ };
type Output = { /*...*/ };
interface VariableMap {[name: string]: Input | Output;
}

那么你可能想要一个将名字(name)附加到变量上的类型,如:

type NamedVariable = (Input | Output) & {name: string};

这个类型无法用 interface 来表达。一般来说,type 比 interface 能力更强。类型可以是一个联合类型,也可以利用更高级的特性,如映射类型(mapped)和条件类型(conditional)。

它还可以更容易地表达元组和数组类型:

type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];

你可以用 interface 来表达类似元组的东西:

interface Tuple {0: number;1: number;length: 2;
}
const t: Tuple = [10, 20]; // OK

但这很笨拙,而且放弃了所有的元组方法,如 concat,所以最好使用 type。

不过,interface 确实有一些 type 没有的能力。其中之一就是 interface 可以被扩增。比如:

interface IState {name: string;capital: string;
}
interface IState {population: number;
}
const state: IState = {name: 'China';capital: 'BeiJing';population: 5000000;
}; // OK

这就是所谓的 “声明合并” ,如果你从来没见过这种写法,它会让你很惊讶。它主要用于类型声明文件,如果你正在编写一个类型声明文件,你就应该遵循该规范,并使用 interface 来支持它。这样做,是因为你的类型声明中可能会缺少一些需要用户补充的属性,这时候用户就会使用声明合并。

对于没有既定风格的项目,你应该考虑扩增。你是否在为一个 API 发布类型声明?如果 API 发生变化时,能够通过 interface 合并新的字段可能对你的用户有帮助,那就使用 interface。但是,对于一个在你项目内部使用的类型,声明合并可能是一个错误,那就倾向于使用 type。

这篇关于精进TypeScript--你了解类型(type)和接口(interface)的区别吗?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/875310

相关文章

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

IDEA如何将String类型转json格式

《IDEA如何将String类型转json格式》在Java中,字符串字面量中的转义字符会被自动转换,但通过网络获取的字符串可能不会自动转换,为了解决IDEA无法识别JSON字符串的问题,可以在本地对字... 目录问题描述问题原因解决方案总结问题描述最近做项目需要使用Ai生成json,可生成String类型

Python中@classmethod和@staticmethod的区别

《Python中@classmethod和@staticmethod的区别》本文主要介绍了Python中@classmethod和@staticmethod的区别,文中通过示例代码介绍的非常详细,对大... 目录1.@classmethod2.@staticmethod3.例子1.@classmethod

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

Golan中 new() 、 make() 和简短声明符的区别和使用

《Golan中new()、make()和简短声明符的区别和使用》Go语言中的new()、make()和简短声明符的区别和使用,new()用于分配内存并返回指针,make()用于初始化切片、映射... 详细介绍golang的new() 、 make() 和简短声明符的区别和使用。文章目录 `new()`

Python中json文件和jsonl文件的区别小结

《Python中json文件和jsonl文件的区别小结》本文主要介绍了JSON和JSONL两种文件格式的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 众所周知,jsON 文件是使用php JSON(JavaScripythonpt Object No

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的