1.是什么
除了string、number、boolean 这种基础的类型之外,在ts类型声明中还存在一些高级的类型应用
这些高级类型,是ts 为了保证语言的灵活性,所使用的一些语言特性。这些特性有助于 我们应该复杂多变的开发场景
2.有哪些
常见的高级类型如下:
- 交叉类型
- 联合类型
- 类型别名
- 类型索引
- 类型约束
- 映射类型
- 条件类型
2.1 交叉类型
通过&将多个类型合并为一个类型,包含了所需的所有类型的特性本质上是一种并的操作
语法如下
T&U
适用于对象合并的场景,如下将声明一个函数,将两个对象合并成一个对象并返回:
function extend<T,U>(first:T,second:U):T&U{
let result:<T&U>={}
for (let key in first){
result[key]=first[key]
}
for (let key in second){
if(!result.hasOwnProperty(key)){
result[key]=second[key]
}
}
return result
}
2.2 联合类型
联合类型的语法规则和逻辑“或”的符号一致,表示其类型为连接多个类型中的任意一个,本质上是一个交的关系
语法如下
T | U
例如:number |string |boolean的类型只能是三个中的一种,不能共存
function formatCommandline(command: string[] | string) {
let line = '';
if (typeof command === 'string') {
line = command.trim(); } else {
line = command.join(' ').trim(); }
}
2.3 类型别名
类型别名会给一个类型起个新名字,类型别名有时和接口很像,但是可以作用于原始值、联合类型、元组以及其它任何你需要手写的类型
可以使用type SomeName =someValidTypeAnnotation的语法来创建类型别名:
type some = boolean | string
const b: some = true // ok
const c: some = 'hello' // ok
const d: some = 123 // “123” “some”
此外类型别名可以是泛型:
type Container<T> = { value: T };
也可以使用类型别名来在属性里引用自己
type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}
可以看到,类型别名和接口使用十分相似,都可以描述一个对象或者函数两者最大的区别在于,interface只能用于定义对象类型,而type以定义交叉、联合、原始类型等,类型声明的方式适用范围显然更加广泛
2.4. 类型索引
keyof 类似于Object.keys,用于获取一个接口中key的联合类型。
interface Button {
type: string
text: string
}
type ButtonKeys = keyof Button
//等效于
type ButtonKeys = "type" | "text"
2.5 类型约束
通过关键字extend进行约束,不同于在class后使用extends的继承作用,泛型内使用的主要作用是对泛型加以约束
type BaseType = string | number | boolean
//这里表示 copy 的参数
// 只能是字符串、数字、布尔这几种基础类型
function copy<T extends BaseType>(arg: T): T {
return arg
}
类型约束通常和类型所以一起使用,例如我们有一个方法专门用来获取对象的值,但是这个对象并不确定,我们
就可以使用extends和keyof进行约束。
function getValue<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
const obj = { a: 1 }
const a = getValue(obj, 'a')
2.6 映射类型
通过in关键字做类型的映射,遍历已有接口的key或者遍历联合类型,如下例子:
type Readonly<T> = {
readonly [P in keyof T]: T[P]; };
interface Obj { a: string
b: string
}
type ReadOnlyObj = Readonly<Obj>
上述结构,可以分成这些步骤:
keyofT:通过类型索引keyof的得到联合类型‘a’:‘b’
P in keyof T等同于 p in ‘a’|‘b’,相当于执行了一次forEach的逻辑,遍历‘a’|‘b’
所以最终ReadOnlyObj的接口为下述:
interface ReadOnlyObj {
readonly a: string;
readonly b: string;
}
2.7 条件类型
条件类型的语法规则和三元表达式一致,经常用于一些类型不确定的情况
T extends U ? X:Y
上面的意思就是,如果T是U的自己,类型就是X,否则就是Y
3 总结
可以看到,如果只掌握了ts的一些基础类型,可能很难游刃有余的去使用ts,需要了解一下ts 的高阶用法
并且ts 在 版本迭代中新增了很多功能,需要不断学习与掌握