Skip to content
On this page

高级类型

交叉类型

取所有类型的并集

ts
interface Dog {
    run(): void
}

interface Cat {
    jump(): void
}

let pet: Dog & Cat  = {
    run() {},
    jump() {}
}

联合类型

声明的类型并不确定,可以为多个类型中的一个

ts
// 字面量联合类型
let method: 'GET' | 'POST' | 'DELETE' | 'PUT'

let a: number | string = 1

索引类型

ts
let obj = {
    a: 1,
    b: 2,
    c: 3
}

function getValues(obj: any, keys: string[]) {
    return keys.map(key => obj[key])
}

console.log(getValues(obj, ['a', 'b'])) // [1, 2]
console.log(getValues(obj, ['e', 'f'])) // [undefined, undefined]

索引操作符 keyof T

ts
interface obj {
    a: number,
    b: string
}

//  obj 字面量的联合类型 number | string
let key: keyof obj
ts
function getValues<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
    return keys.map(key => obj[key])
}

// console.log(getValues(obj, ['e', 'f']))  // error

映射类型

只读类型

ts
interface obj {
    a: string
    b: number
    c: boolean
}

// 类型别名
type ReadonlyObj = Readonly<Obj>

// 等同于
type ReadonlyObj = {
    readonly a: string
    readonly b: number
    readonly c: boolean
}

可选类型

ts
type PartialObj = Partial<Obj>

// 等同于
type PartialObj = {
    a?: string | undefined
    b?: number | undefined
    c?: boolean | undefined
}

抽取部分类型

ts
type PickObj = Pick<Obj, 'a' | 'b'>

// 等同于
type PickObj = {
    a: string
    b: number
}
ts
type RecordObj = Record<'x' | 'y', Obj>

// 等同于
type RecordObj = {
    x: Obj
    y: Obj
}

映射类型就是从旧类型中创建新类型的一种方式。新的类型以相同的形式去转换旧的类型。

条件类型

由条件表达式表示的类型

ts
T extends U ? X : Y
ts
type TypeName<T> = 
    T extends string ? "string" : 
    T extends number ? "number" :
    T extends boolean ? "boolean" : "object"

type T1 = TypeName<string>
type T2 = TypeName<number>

type T3 = TypeName<string | string[]> // 也会是联合类型

联合类型的过滤

ts
type Diff<T, U> = T extends U ? never : T

type T4 = Diff<"a" | "b" | "c", "a" | "e">

实际推断过程拆解为

ts
type T4 = Diff<"a", "a" | "e"> | Diff<"b", "a" | "e"> | Diff<"c", "a" | "e"> // never | b | c

最终得到

ts
type Diff<T, U> = T extends U ? never : T

type T4 = Diff<"a" | "b" | "c", "a" | "e"> // b | c

可以扩展为过滤掉 nullundefined

ts
type NotNull<T> = Diff<T, null | undefined>
type T5 = NotNull<string | number | undefined | null> // string | number

这两个条件类型对应的官方类型;这两个类型实现的效果就是我们上面实现的功能一致

ts
type T6 = Exclude<T, U>

type T7 = NonNullable<T>

抽取相同的类型

ts
// 取交集,抽取相同的类型
type T8 = Extract<"a" | "b" | "c", "a" | "e"> // "a"