购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.2 TypeScript基础与应用

Nest是基于TypeScript进行构建的,它提供了类型安全系统,并引入了面向对象编程、装饰器和元数据等概念。这些概念贯穿于Nest的源码设计和项目实践开发中。本节将从TypeScript的编译配置和类型系统两大板块着手,回顾TypeScript的基础知识。

1.2.1 TypeScript编译

1.编译上下文

TypeScript被设计为JavaScript的超集,在使用时需要通过特定的编译器将其编译为普通的JavaScript才能被浏览器识别。编译器运行的环境被称为TypeScript的编译上下文,它包含编译器需要用到的各种配置选项、输入输出文件等信息。而tsconfig.json文件就是用来指定编译器运行时的行为,即编译选项。

2.编译选项

通常用compilerOptions来定制编译选项,它包含丰富的选项,示例如下:

3.编译运行

TypeScript内置了TSC编译器,可以通过以下方式运行它:

● 运行tsc,它会在当前目录或父级目录中寻找tsconfig.json文件。

● 运行tsc -p ./path-to-project-directory。这里的路径可以是绝对路径,也可以是相对于当前目录的相对路径。

4.指定文件

可以用include和exclude选项来指定需要包含的文件和排除的文件:

1.2.2 TypeScript类型系统

1.基本注解

类型注解使用“:TypeAnnotation”语法。在类型声明空间中,可用的任何内容都可以用作类型注解。

在下面这个例子中,使用了变量、函数参数以及函数返回值的类型注解:

     const num: number = 123;
     function identity(num: number): number {
       return num;
     } 
2.原始类型

JavaScript的原始类型同样适用于TypeScript的类型系统,因此string、number、boolean也可以用作类型注解:

     let num: number;
     let str: string;
     let bool: boolean;

     num = 123;
     num = 123.456;
     num = '123'; // Error
3.数组

TypeScript为数组提供了专用的类型语法,因此我们可以很容易地为数组添加类型注解,代码如下:

     let boolArray: boolean[];

     boolArray = [true, false];
     console.log(boolArray[0]); // true
4.接口

接口可以将多个类型声明合并为一个类型声明:

     interface Name {
       first: string;
       second: string;
     } 

     let name: Name;
     name = {
       first: 'John',
       second: 'Doe'
     };

     name = {
       // Error: 'Second is missing'
       first: 'John'
     };

在这里,我们把类型注解first: string + last: string合并到了一个新的类型注解Name中,这样能够强制对每个成员进行类型检查。

5.特殊类型

除了前面提到的一些原始类型,TypeScript中还存在一些特殊的类型,它们是any、null、undefined以及void。

1)any

any类型为我们提供了一个类型系统的“后门”,使用它时,TypeScript会关闭类型检查。在类型系统中,any能够兼容所有的类型(包括它自己),代码如下:

     let power: any;

     // 赋值任意类型
     power = '123';
     power = 123;

2)null和undefined

在类型系统中,JavaScript中的null和undefined字面量与其他被标注了any类型的变量一样,都可以赋值给任意类型的变量,但不会关闭类型检查,代码如下:

     // strictNullChecks: false

     let num: number;
     let str: string;

     // 这些类型可用于赋值
     num = null;
     str = undefined;

3)void

void表示没有任何类型,通常用于那些不返回任何值的函数的返回类型。

     function myFunction(): void {
       // 函数体
     } 
6.泛型

泛型可以应用于Typescript中的函数(函数参数、函数返回值)、接口和类(类的实例成员、类的方法)。

下面我们来创建第一个使用泛型的示例函数:reverse()。这个函数会返回传入的任意值。在不使用泛型的情况下,这个函数可能是这样的:

     function reverse(arg: any): any {
       return arg;
     };

使用any类型会导致这个函数可以接收任何类型的arg参数,但我们希望传入的类型与返回的类型相同。

因此,需要一种方法来确保返回值的类型与传入参数的类型相同。这里,我们使用了类型变量,它是一种特殊的变量,只用于表示类型而不是值,代码如下:

     function reverse<T>(arg: T): T {
       return arg;
     }

我们给reverse添加了类型变量T。T帮助我们捕获用户传入的类型(比如string),之后把T用作返回值类型,这样就可以跟踪函数中使用的类型信息了。

我们把这个版本的reverse()函数称为泛型,因为它适用于多个类型。

7.联合类型

我们希望JavaScript属性能够支持多种类型,例如字符串或者字符串数组。在TypeScript中,可以使用联合类型来满足这一需求(联合类型使用“|”作为分隔符,例如TypeA | TypeB)。以下是关于联合类型的例子:

8.交叉类型

在JavaScript中,extend是一种非常常见的模式。在这种模式下,我们可以通过两个对象创建一个新对象,使新对象继承这两个对象的所有功能。交叉类型可以让我们安全地使用这种模式:

     function extend<T extends object, U extends object>(first: T, second: U): T & U {
     const result = {} as T & U;

     for (let id in first) {
       (result as T)[id] = first[id];
     } 

     for (let id in second) {
       (result as U)[id] = second[id];
     } 

       return result;
     } 
9.类型别名

TypeScript提供了一种便捷的语法来为类型注解设置别名。我们可以使用type SomeName =someValidTypeAnnotation来创建别名:

     type StrOrNum = string | number;

     // 使用
     let sample: StrOrNum;
     sample = 123;
     sample = '123';

     // 检查类型
     sample = true; // Error
10.类型断言

TypeScript允许覆盖其类型推断,并可以按照我们期望的方式重新分析类型。这种机制被称为“类型断言”。类型断言用于告知编译器,我们对该类型的了解比编译器的推断更为准确,因此编译器不应再发出类型错误。以下是类型断言的常见用法示例:

这里的代码发出了错误警告,因为auth的类型为number|number[],其属性没有some()方法。因此,我们不能使用some()方法。虽然已经知道auth的实际类型是number[],但TypeScript无法推导出这一点。在这种情况下,可以通过类型断言来避免此问题:

11.枚举

枚举是一种用于收集相关值的集合的方法,示例如下:

     enum Status {
       Success,
       Error,
       Warning
     } 

     enum Env {
       Null = '',
       Dev = 'development',
       Prod = 'production'
     } 

     // 简单使用
     let status = Status.Success;
     let env = Env.Dev;
12.重载

TypeScript允许我们声明函数重载。这对于文档+类型安全非常实用。请看以下代码:

我们可以通过函数重载来强制执行并记录这些约束,只需多次声明函数头即可。最后一个函数头在函数体内实际处于活动状态,但这函数头不可在外部直接使用,如下所示:

本节通过示例介绍了TypeScript的基本概念和用法,这些类型在Nest开发中都会频繁使用。掌握本节内容可以为我们以后编写Nest应用打下坚实的基础。 IC4C5PlG14VICwBKRXU8iLBTTJmjZ1xYgc1MDgsjNIZGt8vxmuK9t/Nt54ViPYOv

点击中间区域
呼出菜单
上一章
目录
下一章
×