高级类型
About 8 min
高级类型
交叉类型(&且)
将多个类型叠加合并为一个类型,涵盖所有类型的特性
interface PointX {
x: number
}
interface PointY {
y: number
}
interface PointZ {
z: number
}
// 同时具备多个类型的特性
type PointXYZ = PointX & PointY & PointZ
const pointXYZ: PointXYZ = {
x: 1,
y: 2,
z: 3
}
console.log(pointXYZ)
联合类型(|或)
指定将多个类型联合起来,新的类型可以为多个类型的一种
type typeString = string
type typeNumber = number
type newType = typeString | typeNumber
// arg既可以是string也可以是number类型
function test(arg: newType) {
return arg
}
如果一个值是联合类型,只能访问此联合类型的所有类型里共有的成员
interface Bird {
fly: () => any
layEggs: () => any
}
interface Fish {
swim: () => any
layEggs: () => any
}
function getSmallPet(): Fish | Bird {
// ...
}
const pet = getSmallPet()
pet.layEggs() // okay
pet.swim() // errors
类型区分
利用类型断言,来进行类型区分,有点像指定泛型
interface Bird {
fly: () => any
layEggs: () => any
}
interface Fish {
swim: () => any
layEggs: () => any
}
function getAnimal(): Fish | Bird {
// ...
}
const animal = getAnimal()
animal.layEggs() // okay
animal.swim() // errors
animal.fly() // errors
// 断言为Bird类型
if ((<Bird>animal).fly != null) {
(<Bird>animal).fly()
}
if ((<Fish>animal).swim != null) {
(<Fish>animal).swim()
}
类型保护
- typeof 判断类型, 支持的类型只有四种:
- number
- string
- boolean
- symbol
- instanceof 判断是否为某类的实例化对象
interface Padder {
getPaddingString: () => string
}
class SpaceRepeatingPadder implements Padder {
constructor(private numSpaces: number) {
}
getPaddingString() {
return Array(this.numSpaces + 1).join(' ')
}
}
class StringPadder implements Padder {
constructor(private value: string) {
}
getPaddingString() {
return this.value
}
}
function getRandomPadder() {
return Math.random() < 0.5
? new SpaceRepeatingPadder(4)
: new StringPadder(' ')
}
// 类型为SpaceRepeatingPadder | StringPadder
const padder: Padder = getRandomPadder()
if (padder instanceof SpaceRepeatingPadder) {
padder // 类型细化为'SpaceRepeatingPadder'
}
if (padder instanceof StringPadder) {
padder // 类型细化为'StringPadder'
}
索引类型
利用索引类型查询、索引访问处理
function pluck(o, names) {
return names.map(n => o[n])
}
// keyof T 索引类型查询
// K[T] 索引访问
function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
return names.map(n => o[n])
}
// 字符串索引类型签名
interface Map<T> {
[key: string]: T
}
let keys: keyof Map<number> // string
let value: Map<number>['xxxx'] // number
映射类型
// 只读类型
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
// 可选类型
type Partial<T> = {
[P in keyof T]?: T[P];
}
语法与索引签名的语法类型,内部使用了 for .. in。 具有三个部分:
- 类型变量 K,它会依次绑定到每个属性。
- 字符串字面量联合的 Keys,它包含了要迭代的属性名的集合。
- 属性的结果类型。
有条件类型
Exclude<T, U>
:从T中剔除可以赋值给U的类型。Extract<T, U>
:提取T中可以赋值给U的类型。NonNullable<T>
:从T中剔除null和undefined。ReturnType<T>
:获取函数返回值类型。InstanceType<T>
:获取构造函数类型的实例类型
type T00 = Exclude<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'> // "b" | "d"
type T01 = Extract<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'> // "a" | "c"
// string | number
type T02 = Exclude<string | number | (() => void), Function>
// () => void
type T03 = Extract<string | number | (() => void), Function>
// string | number
type T04 = NonNullable<string | number | undefined>
// (() => string) | string[]
type T05 = NonNullable<(() => string) | string[] | null | undefined>
function f1(s: string) {
return { a: 1, b: s }
}
class C {
x = 0
y = 0
}
type T10 = ReturnType<() => string> // string
type T11 = ReturnType<(s: string) => void> // void
type T12 = ReturnType<(<T>() => T)> // {}
type T13 = ReturnType<(<T extends U, U extends number[]>() => T)> // number[]
type T14 = ReturnType<typeof f1> // { a: number, b: string }
type T15 = ReturnType<any>
// anytype T16 = ReturnType<never>;
// anytype T17 = ReturnType<string>;
// Errortype T18 = ReturnType<Function>;
// Errortype T20 = InstanceType<typeof C>;
// Ctype T21 = InstanceType<any>;
// anytype T22 = InstanceType<never>;
// anytype T23 = InstanceType<string>;
// Errortype T24 = InstanceType<Function>; // Error
// 没有Omit<T,K>,可以采用等价写法
Pick<T, Exclude<keyof T, K>>