TypeScript高级语法
在线运行 TypeScript https://www.typescriptlang.org/play
typeof
typeof val
获取对象的类型
- 已知一个 javascript 变量,通过 typeof 就能直接获取其类型
const str = 'foo'
typeof str === 'string' // true
const user = {
name: 'kuizuo',
age: 12,
address: {
province: '福建',
city: '厦门',
},
}
type User = typeof user
// {
// name: string;
// age: number;
// address: {
// province: string;
// city: string;
// };
// }
type Address = (typeof user)['address']
// {
// province: string;
// city: string;
// }
- 获取函数的类型(参数类型与返回值类型)
function add(a: number, b: number): number {
return a + b
}
type AddType = typeof add
// (a: number, b: number) => number
type AddReturnType = ReturnType<typeof add>
// number
type AddParameterType = Parameters<typeof add>
// [a: number, b: number]
keyof
keyof T
获取 T 类型中的所有 key,类似与 Object.keys(object)
根据 key 获取对象其属性的例子
function getProperty<T extends object, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
上面代码有很好的代码提示,并且如果获取的 key 不在其对象中,将会直接报错。
对于一些常用类型的 keyof 值
type K0 = keyof string
// number | typeof Symbol.iterator | "toString" | "charAt" | ... more
type K1 = keyof boolean
// "valueOf"
type K2 = keyof number
// "toString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" | "toLocaleString"
type K3 = keyof any
// string | number | symbol
交叉类型
& 交叉运算符
类似集合中的交集,满足以下特性
- 唯一性:A & A 等价于 A
- 满足交换律:A & B
- 满足结合律:(A & B) & C 等价于 A & (B & C)
- 父类型收敛:如果 B 是 A 的父类型,那么 A & B 将收敛为 A 类型.
任何与 never 交叉的类型都是 nerver,any 交叉的类型为 any(除了 nerver)
type A0 = any & 1 // any
type A1 = any & boolean // any
type A2 = any & never // never
type A3 = string & number // never
映射类型
{ [P in K]: T }
其中 in 类似与 for ...in 语句,而 T 类型表示任意类型。遍历 K 类型的所有 key,生成 P : T,例如
interface Todo {
title: string
description: string
completed: boolean
}
type Demo<T> = { [P in keyof T]: T }
type Todo1 = Demo<Todo>
// {
// title: string
// description: string
// completed: boolean
// }
上面代码看似没有任何映射关系,因为在映射类型中可以给对其添加readonly 和 ? 只读与可选修饰符,以及+ - 增加与删除修饰符(默认为+)例如
{ [ P in K] :T }
{ [ P in K] ?:T }
{ [ P in K] -?:T }
{ readonly [ P in K] :T }
{ readonly [ P in K] ?:T }
{ -readonly [ P in K] ?:T }
就可以实现一些 TypeScript 的内置工具类(给对象属性只读,可选等等)
type MyPick<T, K extends keyof T> = {
[P in K]: T[P]
}
type MyPartial<T> = {
[P in keyof T]?: T[P]
}
type MyRequired<T> = {
[P in keyof T]-?: T[P];
}
type MyReadonly<T> = {
readonly [P in keyof T]: T[P]
}
...
条件类型
T extends U ? X : Y
其代码语法类似与三元运算符,
- 如果 T 和 U 都为基本类型两侧相同,则 extends 在语义上可以理解为 ===
type Demo1 = 'foo' extends 'bar' ? true : false // false
type Demo2 = 'c' extends 'c' ? true : false // true