概述 Typescript 的高级类型指操作基本类型和复合类型而得的类型,包括: 联合 交叉 泛型 类型别名 在讲具体的高级类型之前,我们先了解一下 Typescript 的类型别名。类型别名也是一种类型,…
#### 概述
Typescript 的高级类型指操作基本类型和复合类型而得的类型,包括:
联合
交叉
泛型
类型别名
在讲具体的高级类型之前,我们先了解一下 Typescript 的类型别名。类型别名也是一种类型,用一个单词代表可能比较复杂的类型声明,用关键字
1 | type |
表示。
示例:
1 | type S = string |
这里用
1 | S |
作为
1 | string |
的别名,使用方法和
1 | string |
一模一样。
别名不仅可以代表基本类型,它可以代表任意类型。示例:
1 | type SA = string[] // 代表字符串数组 |
类型
联合
联合类型是指变量为多个类型中的一种,是“或”的关系,用操作符
1 | | |
表示。
示例:
1 | type StringOrNumber = string | number |
这里
1 | StringOrNumber |
表示一种可以是字符串或者也可以是数字的类型,所以对于
1 | StringOrNumber |
类型的变量,既可以赋值为字符串,也可以赋值为数字。
在 Typescript 中,
1 | null |
和
1 | undefined |
与其它类型是同层级的,它们不是任何类型的子类型,也就是说我们不能用它们来表示一个特定类型的空指针。但是我们确实需要在一个变量未确定时保持为空状态,这时可以用联合类型来表示一个变量可为
1 | null |
或
1 | undefined |
。示例:
1 | interface A { |
字面量类型
Typescript 中字面量也可以作为一个类型。比如:
1 | let a: 'A' |
上述声明表示变量
1 | a |
的值只能是
1 | 'A' |
,赋值为其它值时会报错。
数字和布尔也可以作为字面量类型。这看起来没什么用,但是这种特性一般会与联合结合起来使用。比如:
1 | type Option = 'A' | 'B' | 'C' | 'D' |
1 | Option |
类型的变量只能被赋值为
1 | 'A' |
、
1 | 'B' |
、
1 | 'C' |
、
1 | 'D' |
���中一个值。这一种用法和枚举很像,比如:
1 | enum Option { |
不同的是,字面量类型本质上是字符串,可以使用字符串的所有方法。而且,通过
1 | keyof |
操作符,我们可以动态的生成字面量类型,这一点将在之后介绍。
交叉
交叉类型是指多个类型合并成一个类型,是“且”的关系,用操作符
1 | & |
表示。
示例:
1 | interface A { |
交叉类型的成员包含了所有原类型的的所有成员,比如上述代码中,
1 | c |
变量必须既是
1 | A |
类型也是
1 | B |
类型,也就是说它必须同时拥有两个类型要求的属性。
有一些类型是无法交叉的,比如基本类型。示例:
1 | type A = string & number |
因为一个变量不可能既是字符串又是数字,所以最终
1 | A |
类型是
1 | never |
类型。
如果被交叉的两个类型有同名但类型不同的成员,那么这两个同名成员也会被交叉。示例:
1 | interface A { |
类型
1 | A |
和
1 | B |
有同名但类型不同的成员
1 | x |
,交叉时两个
1 | x |
成员也可以交叉,因此最终
1 | x |
的类型为:
1 | {a: string, b: number, c: number} |
。
泛型
Typescript 中的泛型与其它面向对象语言中的泛型和相似,包括:泛型函数、泛型类和泛型接口。
泛型函数
示例:
1 | function merge<T, U>(x: T, y: U): { x: T; y: U } { |
我们可以在中括号内声明函数中使用到的泛型变量,它代表了在调用函数时传入的类型。类型变量
1 | T |
可以用在任何需要类型声明的地方,比如参数类型、返回值类型、局部变量类型等。
箭头函数也可以包含泛型。示例:
1 | const merge = <T, U>(x: T, y: U): { x: T; y: U } => { |
泛型类
示例:
1 | class Merge<T, U> { |
我们可以在中括号内声明类中使用到的泛型变量,它代表了在实例化类时传入的类型。类型变量
1 | T |
可以用在任何需要类型声明的地方,比如成员、构造方法参数类型等。
泛型接口
示例:
1 | interface Merge<T, U> { |
我们可以在中括号内声明接口中使用到的泛型变量,它代表了在声明变量类型时传入的类型。类型变量
1 | T |
可以用在任何需要类型声明的地方,比如成员、方法参数类型等。
泛型约束
由于在泛型类型中,泛型变量是在使用时传入的,所以在编译时无法得知其具体类型,那么读取类类型变量的任何成员都是不行的。比如:
1 | function scale<T>(x: T): number { |
虽然我们可能心里知道在使用时我们会传入一个具有
1 | length |
成���的变量(比如字符串),但是在编译时编译器并不知道。因此,我们需要告诉编译器
1 | T |
类型是那一类具有
1 | length |
成员的类型。使用
1 | extends |
关键字:
1 | interface HasLength { |
我们使用
1 | extends |
对类型变量
1 | T |
进行了约束,它必须具有
1 | length |
属性。也就是是说
1 | T |
类型必须实现或继承了 HasLength 类型。
本文标题: 推荐系列--Typescript小小册-高级类型
本文作者: OSChina
发布时间: 2021年04月15日 09:48
最后更新: 2023年06月29日 07:10
原始链接: https://haoxiang.eu.org/140bd56a/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!