进阶类型
- 类型别名
类型别名用来给一个类起个新名字
type Name = string;
type NameResoleve = () => string
type NameOrResolve = Name | NameResoleve
function getName(n: NameOrResolve): Name {
if (typeof n == 'string') {
return n
}else{
return n()
}
}
- 联合类型 通过 | 来联合
只能访问联合类型中 所有类型中都有的属性 - 交叉类型 通过 & 来联合
将多个类型合并为一个类型,包含了所有类型中的特性
interface Iperson {
id: string;
age: number;
}
interface Iworker {
companyId: string;
}
type Istaff = Iperson & Iworker
上面新生成的类型, 就相当与定义了
interface Istaff {
id: string;
age: number;
companyId: string;
}
- 字符串字面量
用来约束取值只能是字符串中某几个中的一个
type EventNames = 'click' | 'scroll' | 'mousemove'
function handleEvent (ele: Element, event: EventNames) {
}
handleEvent(document.getElementById('id'), 'click')
- 类型断言
手动指定一个值的类型
let someValue: any = 'i am string'
let stringLength: number = (<string>someValue).length
等价于
let stringLength: number = (someValue as string).length
可以将父类断言为一个更加具体的子类
class apiError extends Error {
code: number = 0
}
class httpError extends Error {
statusCode: number = 200
}
function isApiError (error: Error) {
if (typeof (error as apiError).code == 'number') {
return true
}
return false
}
- 操作符
- typeof 获取一个变量申明或者一个对象的类型
interface Person {
name: string;
}
const tom: Person = {name: 'tom'}
type Tom = typeof tom // --> Person
function toArray (x: number): Array<number> {
return [x]
}
type Func = typeof toArray // (x: number) => number[]
- keyof 获取一个类型中所有的key
interface Person {
name: string;
age: number;
}
type k1 = keyof Person // 'name' | 'age'
const me: Person = {name: 'name', age: 16}
type PersonKey = keyof typeof me // 'name' | 'age'
- in 遍历类型
type Keys = 'a' | 'b'
下面遍历这个联合类型
type Obj = {
[p in keys]: number
}
// -> {a: number; b: number}
- 可选操作符 ?:
- 泛型
泛型是指在定义函数, 接口, 类的时候,不预先指定类型,而在使用的时候再指定类型的一种特性
function merge<T> (a: T, b: T): T[] {
return [a, b]
}
merge<string>('a', 'b')
// 这里显示的定义了 T 是 string 那就是定义了 a, b ,以及返回的数组中都是 string
merge(1,2)
// 这里是隐式定义了 T 是 number
merge<number>('a', 1)
// 这里就会报错了
多个类型参数, 就是用多个参数来定义类型
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]]
}
泛型约束
在不知道 泛型的类型的时候,不能随便去使用属性, 如果要使用的话,需要告诉泛型 ,他属于某种约束,这样就可以使用约束的属性
interface lengthwise {
length: number;
}
function loggingIdenticy<T extends lengthwise> (arg: T): T {
console.log(arg.length)
return arg
}
这样就限制了 传递的参数,必须要满足 lengthwise 的约束
泛型接口
在定义接口的时候,不指定具体的类型, 在定义的时候,将类型传递给接口
interface Person<T> {
name: T
}
const tom: Person<string> = {name: 'zhangsan'}
const jerry: Person<number> = {name: 33}
泛型类
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T
}
let myGenericNumber = new GenericNumber<number>()
myGenericNumber.zeroValue = 0
myGenericNumber.add = (x, y) => {return x + y}
- 条件类型
语法表达式 比较像 三元运算符
type isString <T> = T extends string ? true: false
type T1 = isString<'a'>
type T2 = isString<1>
type T3 = isString<1 | 'a'>
传入的参数 满足是 string 就返回 true 否则返回 false
第三种方式传入的参数 会分别判断, 返回 true | false 就是 boolean
9. 条件推断
在条件类型语句中,可以使用infer 申明一个类型变量并且对他进行使用
type getType<T> T extends {a: infer U} ? U : never
type T1 getType<{a: string}> //string
getType 接收的参数类型 符合 {a: infer U} ,在这里 不管a 是什么类型, 只要满足这个结构就可以, 返回的就是 a 的类型
type T2 getType<number> // never
在这里 不满足 {a: infer U} 所以返回的是 never
type T3 getType<{a: number; b: string}> // number
应用场景 :使用条件推断 来获取数组元素类型
type unpack<T> = T extends (infer U)[] ? U : never
type T1 = unpack<number[]> // number
type T2 = unpack<string[]> // string
获取函数返回类型
type returnType<T> = T extends (...arg: any[]) => infer U ? U : never
获取函数参数类型
type Parameters<T extends (...args: any) => any> = T extends (...args: infer U) => any ? U : never
- 内置类型
- 根据一个定义好的类型,将该类型中的key 修改为可选参数
type Partial <T> {
[p in keyof T]?: T[P]
}
type Animal = {
name: string;
age: number;
eat: () => number
}
type PartOfAnimal = Partial<Animal>
const ww: PartOfAnimal = {name: 'ww'}
- 将传入的类型都变为必选属性, 包括可选属性
type Required<T> = {
[p in keyof T]-?: T[p]
}
- 只把传入的属性获取出来,作为一个类返回
type Pick <T, K extends keyof T> {
[p in K]: T[P]
}
type Animal = {
name: string;
age: number;
eat: () => number
}
const bird: Pick<Animal, 'name' | 'age'> = {name: 'zs', age: 23}
下一篇将继续介绍 高级用法