上篇文章中简单介绍了 keyof 操作符
下方 Keyof 的返回的类型似于 “x” | "y"
type Point = {x: number; y: number}
type P = Keyof Point
索引签名
类型中有索引签名的时候,Keyof返回的是 number 类型
type Arrayish = { [n: number]: unknow }
// number
type A = Keyof Arrayish
有一个特殊现象,由于 JS 中对象的key都会被转化为 string,因此当指定 key 为 string的时候有如下表现
type Mapish = { [k: string]: boolean }
// string | number
type M = Keyof Mapish;
Mapped Types
Mapped Types 是建立在对象索引签名的格式上,被用来声明一个未在第一时间声明的对象属性。通常使用 Keyof 操作符
type OptionsFlags<T> = {
[P in Keyof T]: boolean
}
利用 Mapped Types 实现 Partical
type Partical<T> = {
[P in keyof T]?: T[P]
}
Mapping Modifiers
利用 - readonly 移除属性的只读限制,利用-?移除属性的可选限制
type CreateMutable<T> = {
-readonly [P in Keyof T]: T[P]
}
type LockedAccount = {
readonly id:string;
readonly name:string;
}
type UnlockAccount = CreateMutable<LockedAccount>
type Concrete<T> = {
[P in keyof T]-?: T[P]
}
type MaybeUser = {
id: string;
name?: string;
age?: number;
}
type User = Concrete<MaybeUser>
as
TS 4.1 新特性,可以使用 as 重新命名 properties
下方,结合字面量使用
Capitalize是将首字母大写,其泛型类型受限为string。但是,Property 可能是 number、string、symbol之一。一次不符合条件,所以使用 string & Property 对类型进行限制。
type Getters<T> = {
[P in Keyof T as `get${Capitalize<string & Property>}`]: () => T[P]
}
interface Person{
name: string;
age: number;
location: string
}
// getName:() => string
// etc.
type LazyPerson = Getters<Person>
拓展 ---> type的 & 操作
注意:两个interface & 操作的时候,对于共同的属性,会把每个属性都进行 & 操作;对于多余的属性,直接添加即可。
// a 的类型为 'string'
type a = string & 'test'
// c 的类型为 string
type b = string | number | symbol
type c = b & string
// d 的类型为 never
type d = string & number
// 两个interface 操作
interface e {
a: number
}
interface f {
a: string
d: number
}
// e的类型为 a:never d:number
type e = e & f