精进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

相关文章

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

关于Mybatis和JDBC的使用及区别

《关于Mybatis和JDBC的使用及区别》:本文主要介绍关于Mybatis和JDBC的使用及区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、JDBC1.1、流程1.2、优缺点2、MyBATis2.1、执行流程2.2、使用2.3、实现方式1、XML配置文件

Java对接Dify API接口的完整流程

《Java对接DifyAPI接口的完整流程》Dify是一款AI应用开发平台,提供多种自然语言处理能力,通过调用Dify开放API,开发者可以快速集成智能对话、文本生成等功能到自己的Java应用中,本... 目录Java对接Dify API接口完整指南一、Dify API简介二、准备工作三、基础对接实现1.

exfat和ntfs哪个好? U盘格式化选择NTFS与exFAT的详细区别对比

《exfat和ntfs哪个好?U盘格式化选择NTFS与exFAT的详细区别对比》exFAT和NTFS是两种常见的文件系统,它们各自具有独特的优势和适用场景,以下是关于exFAT和NTFS的详细对比... 无论你是刚入手了内置 SSD 还是便携式移动硬盘或 U 盘,都需要先将它格式化成电脑或设备能够识别的「文

什么是ReFS 文件系统? ntfs和refs的优缺点区别介绍

《什么是ReFS文件系统?ntfs和refs的优缺点区别介绍》最近有用户在Win11Insider的安装界面中发现,可以使用ReFS来格式化硬盘,这是不是意味着,ReFS有望在未来成为W... 数十年以来,Windows 系统一直将 NTFS 作为「内置硬盘」的默认文件系统。不过近些年来,微软还在研发一款名

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的