不要再混淆TypeScript的类型别名和接口了

图片

掌握Type和Interface的异同,了解它们的使用场景

如果你在简历上写过TypeScript,那么面试官可能会问你类型别名和接口的区别是什么。你知道怎么回答这个问题吗? 如果你不知道,读完这篇文章后你可能就会明白了。

类型别名可以用来给类型一个新的名字,并且在命名非对象类型(如基本类型或联合类型)时很有帮助,如:

type MyNumber = number;type StringOrNumber = string | number;type Text = string | string[];type Point = [number, number];type Callback = (data: string) => void;

在TypeScript 1.6中,类型别名开始支持泛型类型。在我们的工作中经常使用的实用程序类型,如Partial、Required、Pick、Record和Exclude,是用类型别名定义的。

图片

在定义对象类型时,通常使用 interface 。Vue 3中的App对象是使用interface定义的:

图片

从上面的代码中可以看到,在定义接口时,我们可以在对象类型上声明属性和方法。

在理解了类型别名和接口的作用之后,让我们来介绍它们之间的相似之处。

相似之处
 

  1. 类型别名和接口都可以用来描述对象或函数类型。

类型别名

type Point = {  x: number;  y: number;};
type SetPoint = (x: number, y: number) => void;

在上面的代码中,我们使用type关键字分别为对象字面量类型和函数类型定义了别名,以便这些类型可以在其他地方使用。

接口

interface Point {  x: number;  y: number;}
interface SetPoint {  (x: number, y: number): void;}

2. 类型别名和接口都可以扩展

类型别名用 & 扩展,接口用 extends 扩展。

图片

那么接口可以通过extends扩展类型别名定义的类型吗? 答案是肯定的。此外,类型别名还可以通过 & 操作符扩展已定义的接口类型:

图片

现在我们知道了类型别名和接口之间的相似之处,让我们再来谈谈它们之间的区别。

差异
 

  1. 类型别名可以为基本类型、联合类型或元组类型定义别名,而接口不能:

type MyNumber = number; // primitive typetype StringOrNumber = string | number; // union typetype Point = [number, number]; // tuple type

2. 具有相同名称的接口会自动合并(声明合并),而类型别名不会:

图片

使用声明合并的特性,我们可以在开发第三方库时为用户提供更好的安全性。例如,webeext -bridge库使用interface定义了ProtocolMap接口,以便用户可以自由扩展ProtocolMap接口。之后,当使用库中提供的onMessage函数监视自定义消息时,我们可以推断出与不同消息对应的消息体类型。

扩展了ProtocolMap接口​​​​​​​

import { ProtocolWithReturn } from 'webext-bridge'
declare module 'webext-bridge' {  export interface ProtocolMap {    foo: { title: string }    bar: ProtocolWithReturn<CustomDataType, CustomReturnType>  }}

监听自定义消息​​​​​​​

import { onMessage } from 'webext-bridge'
onMessage('foo', ({ data }) => {  // type of `data` will be `{ title: string }`  console.log(data.title)}

图片

如果您感兴趣,请查看webext-bridge中onMessage的类型定义。

最后,让我们总结一下类型别名和接口的一些使用场景。

何时使用 type

  1. 在为基本类型定义别名时,使用 type

  2. 定义元组类型时,使用 type

  3. 定义函数类型时,使用 type

  4. 定义联合类型时,使用 type

  5. 在定义映射类型时,使用 type


何时使用 interface

  1. 当您需要利用声明合并特性时,请使用 interface

  2. 当定义对象类型而不需要使用type时,使用 interface


读完本文之后,相信您已经理解了类型别名和接口之间的区别了。

欢迎关注微信公众号:文本魔术,了解更多 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值