深入TypeScript,掌握接口和泛型

您所在的位置:网站首页 typescript泛型约束 深入TypeScript,掌握接口和泛型

深入TypeScript,掌握接口和泛型

2023-06-22 20:15| 来源: 网络整理| 查看: 265

1. 前言

这篇文章主要介绍TypeScript的接口声明interface和泛型,这两个是在实际项目开发中比较常用的,所以单独写一篇文章介绍。

如果想从0开始学习TypeScript的同学,极力推荐我之前的写的文章:

邂逅TypeScript,搭建简易ts开发环境 - 掘金

初始TypeScript,认识类型和类型操作 - 掘金

深入TypeScript,函数详解 - 掘金

学习本文,你将学到:

1. 学会接口的使用; 2. 了解接口和类型别名的区别; 3. 学会泛型的使用; 6. 等等 复制代码 2. 接口 interface

之前的文章说过命名对象类型可以使用type,而接口声明(interface declaration)是命名对象类型的另一种方式:

interface IInfo { name: string age?: number // 可选类型 } const info: IInfo = { name: 'james', age: 20 } info.age // ok info.name // ok 复制代码

TypeScript 只关心传递给 info的值的结构)——关心值是否有期望的属性。正是这种只关心类型的结构和能力的特性,我们才认为TypeScript是一个结构化的类型系统。

类型别名和接口的区别:

类型别名和接口非常相似,大部分时候,你可以任意选择使用。接口的几乎所有特性都可以在 type 中使用,两者最关键的差别在于类型别名本身无法添加新的属性,而接口是可以扩展的:

// 接口 可以通过扩展(extends)新增属性 interface Person { name: string } interface Student extends Person { stuNo: string } const stu: Student = { name: 'hsh', stuNo: '01' } stu.name // ok stu.stuNo // ok // 类型别名 通过交集(&)扩展类型 type Person = { name: string } type Student = Person & { stuNo: string } const stu: Student = { name: 'hsh', stuNo: '01' } stu.name // ok stu.stuNo // ok 复制代码

接口还可以对已经存在的接口添加新的属性,而type不能:

// 接口可以对一个已经存在的接口添加新的字段 interface Message { content: string } interface Message { contentType: string } const msg: Message = { content: 'message', contentType: 'text' } msg.content // ok msg.contentType // ok // type // Error:标识符“Message”重复 type Message { content: string } type Message { contentType: string } 复制代码

那么在实际开发过程中,具体怎么选择是使用type还是interface呢?官方文档中是这么说的:

For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type.

翻译:大部分时候,你可以根据个人喜好进行选择。TypeScript 会告诉你它是否需要其他方式的声明。如果你喜欢探索性的使用,那就使用 interface ,直到你需要用到 type 的特性。

2. 泛型

我们先看下官方文档对泛型的介绍:

A major part of software engineering is building components that not only have well-defined and consistent APIs, but are also reusable. Components that are capable of working on the data of today as well as the data of tomorrow will give you the most flexible capabilities for building up large software systems.

In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.

翻译:软件工程的一个重要部分就是构建组件,组件不仅需要定义良好和一致的 API,也需要是可复用的。好的组件不仅能够兼容今天的数据类型,也能适用于未来可能出现的数据类型,$这在构建大型软件系统时会给你最大的灵活度。

在比如 C# 和 Java 语言中,用来创建可复用组件的工具,我们称之为泛型。利用泛型,我们可以创建一个支持众多类型的组件,这让用户可以使用自己的类型自定义这些组件。

TypeScript中泛型的定义:在定义函数时,不决定函数的参数类型,而是让调用者以参数的形式告知,函数的参数应该是什么样的类型。

使用泛型之前,我们写函数的类型,是这样的:

function identity(arg: any): any { return arg; } 复制代码

尽管使用 any 类型可以让我们接受任何类型的 arg 参数,但也让我们丢失了函数返回时的类型信息。如果我们传入一个数字,我们唯一知道的信息是函数可以返回任何类型的值。

所以我们需要一种可以捕获参数类型的方式,然后再用它表示返回值的类型。

function identity(arg: Type): Type { return arg; } 复制代码

这个Type允许我们捕获调用者提供的类型,使得接下来可以使用这个类型,可以看到,返回值也使用了这个类型。这就是泛型。函数的参数和返回值的类型不是固定的,而是由函数的调用者决定的。

我们有两种方式调用上边的泛型函数:

传入所有的参数(包括类型参数)

let output = identity("myString"); // output: string 复制代码

在这里,我们使用 而不是 ()包裹了参数,并明确的设置 Type 为 string 作为函数调用的一个参数;

使用类型推导

let output = identity("myString"); // let output: string 复制代码

这次我们并没有用 明确的传入类型,当编译器看到 myString 这个值,就会自动设置 Type 为它的类型(即 string)。

泛型接口的使用

接口中也可以使用泛型:

// 可以同时传入多个类型 interface User { name: T, age: N } const user: User = { name: 'hsh', age: 18 } user.name // ok user.age // ok 复制代码

泛型约束

有些时候,需要对Type做一些类型约束,以保证顺利通过编译。

假如现在有一个getLength函数:

function getLength(arg: T) { console.log(arg.length); // Error: 类型“T”上不存在属性“length” } 复制代码

上边的写法会直接报错,因为Type可能是任意类型,而如果是number类型的话,是没有length属性的,这个时候要对泛型进行类型约束:

// 使用接口约束 interface ILength { length: number } function getLength(arg: T) { console.log(arg.length); } getLength('111') // ok getLength(['111']) // ok // getLength(111) // Error: 类型“number”的参数不能赋给类型“ILength”的参数 复制代码

现在这个泛型函数被约束了,它不再适用于所有类型,我们需要传入符合约束条件的值。

3. 总结

这篇文章主要熟悉了TypeScript中的接口(interface)和泛型的使用,这里推荐一个个人感觉翻译的比较好的TypeScript中文网站 TypeScript4 中文文档 。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3