進階類型
- 類型別名
類型別名用來給一個類起個新名字
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}
下一篇將繼續介紹 高級用法
浙公網安備 33010602011771號