TypeScript 的流行程度不必多说,虽然我已工作近 4 年,但还没有正式使用过 TypeScript,只是在学习与 Demo 项目上试用过,现在我认为有必要认真学习与使用了,故此系列记录我学习 TypeScript 的历程。
学习技术先从官方文档看起,推荐看英文的,可以结合翻译插件(推荐 沉浸式翻译 ,双语显示原文与翻译,免费开源)。本文将会翻译 TypeScript for JavaScript Programmers 并结合我的个人理解进行扩展。
TypeScript 与 JavaScript 有着不同寻常的关系。 TypeScript 提供了 JavaScript 的所有功能,以及在这些功能之上附加了 TypeScript 的类型系统。
TypeScript 并不复杂,它只不过是加了个类型系统而已
这意味着您现有的 JavaScript 代码也是 TypeScript 代码。 TypeScript 的主要好处是它可以突出代码中的意外行为,从而降低出现错误的可能性。
TypeScript 能把一些通常意义上的错误暴露出来,而 JavaScript 却不行,比如:不小心把数字类型变量赋值成了字符串类型,TypeScript 会提示报错,而 JavaScript 只有在运行时才能发现
本教程简要概述了 TypeScript,重点介绍了它的类型系统。
类型推断
TypeScript 理解 JavaScript 语言,并会在多数情况下为您自动生成类型。例如,在建变量并给出默认值时,TypeScript 将使用该值作为其类型。
helloWorld 变量默认值是 string 类型,所以 TypeScript 推断 helloWorld 变量就是 string 类型,所以可以省略显示类型声明:
let helloWorld: string = "Hello World";。由此可见 TypeScript 推荐你在声明变量时给默认值
通过理解 JavaScript 的工作原理,TypeScript 可以构建一个输入 JavaScript 代码但具有类型的系统,并且无需添加额外的字符来在代码中明确显示类型。
如 TypeScript 知道 helloWorld 是 string 类型,就能自动提示 string 的方法,而 JavaScript 不行
定义类型
您可以在 JavaScript 中使用多种设计模式。但是,某些设计模式使得自动推断类型变得困难(例如,使用动态编程的模式)。为了涵盖这些情况,TypeScript 支持 JavaScript 语言扩展,它支持显示定义 TypeScript 类型。
例如,要创建一个包含 name: string 和 id: number 的推断类型的对象,您可以编写:
您可以使用 interface 声明明确描述此对象的形状:
然后,通过在变量声明后使用 : TypeName 的语法来声明 JavaScript 对象符合新的 interface 的形状:
如果你提供的对象与你提供的接口不匹配,TypeScript 会警告:
JavaScript 支持类和面向对象编程,TypeScript 也支持。您可以对类使用接口声明:
您可以使用接口来注释函数的参数与返回值:
JavaScript 中已经有一些基本类型可以在接口中使用:boolean、 bigint、 null、number、 string、 symbol和 undefined。TypeScript 又扩展了,例如 any (允许任何类型)、unknown (确保使用此类型的人声明类型是什么)、 never (这种类型不可能发生)和 void (返回 undefined 或没有返回值的函数)。
构建类型有两种语法:Interfaces 和 Types。您应该优先使用 interface 。
这里说的很明确,要优先使用
interface,用不了的话,再用type
组合类型
使用 TypeScript,可以通过组合简单类型来创建复杂类型。有两种流行的方法可以做到这一点:联合和泛型。
联合(Unions)
使用联合,可以声明一个类型可以是多种类型之一。例如,可以将 boolean 类型描述为 true 或 false :
注意:如果将鼠标悬停在上面的 MyBool 上,您会看到它被归类为 boolean 。这是结构类型系统的一个属性。更多内容请见下文。
联合类型的一个通常用法是描述一组 string 或 number 字面量:
联合也提供了一种处理不同类型的方法。例如,有一个接受 array 或 string 的函数:
要获取变量的类型,请使用 typeof :
根据传递给函数的是字符串还是数组来使函数返回不同的值:
泛型(Generics)
泛型支持了类型变量。
一个常见的例子是数组。没有泛型的数组(JavaScript 中的数组)可以包含任何东西。具有泛型的数组可以描述数组内的值的类型。
声明使用泛型的类型:
结构类型系统
TypeScript 的核心原则之一是类型检查侧重于值的形状。这有时被称为“鸭子类型”或“结构类型”。
在结构类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型。
point 变量不是 Point 类型。但是,TypeScript 在类型检查中将 point 的形状与 Point 的形状进行比较。它们具有相同的形状,因此代码没有报错。
并且形状匹配只需要匹配对象字段的一个子集。
对于符合形状,类和对象没有区别:
如果对象或类具有所有必需的属性,TypeScript 会认为它们匹配,而不管实现细节。
鸭子类型,这里解释的很到位
下一步就是阅读手册了,我们下一篇见~