TypeScript的泛型工具集合
TypeScript中集合了很多泛型工具,在日常开发中,我们经常会看到这类工具的使用,所以属性这类工具也是必备的。
工具集大概能够分为几类:
- 对象与属性工具
- 联合类型工具
- 函数工具
- 类工具
- 字符串工具
- this工具
- promise工具
对象与属性工具
Partial<T>
将类型的所有属性设置为可选属性
ts
interface User {
id: number;
name: string;
age: number;
}
const user2: Partial<User> = { id: 2, name: "ErMao" };
Required<T>
将类型的所有属性设置为必填
ts
interface Config {
port?: number;
host?: string;
}
const c1: Config = { port: 8080 };
const c2: Required<Config> = { port: 8080, host: "localhost" };
Readonly<T>
将类型的所有属性设置为只读
ts
interface Todo {
title: string;
done: boolean;
}
const t: Readonly<Todo> = { title: "Clean", done: false };
// t.done = true // 错误:不能分配到 "done" ,因为它是只读属性
Record<K,T>
用联合类型键映射到统一的值类型。这个工具很特别,可以把类型作为对象的键。
ts
type Status = "success" | "error" | "loading";
const statusMap: Record<Status, string> = {
success: "成功",
error: "错误",
loading: "加载中",
};
Pick<T, K>
从类型 T 中选择一组属性 K
ts
interface User {
id: number;
name: string;
age: number;
}
const u3: Pick<User, "id" | "name"> = { id: 2, name: "ErMao" };
Omit<T, K>
从类型 T 中排除一组属性 K
ts
interface TodoList {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
type TodoWithoutMeta = Omit<TodoList, "createdAt" | "completed">;
const x: TodoWithoutMeta = { title: "Clean", description: "Room" };
从这些方法中,可以从对象的键数量和属性进行记忆:
多 >>> 少:Partial、Pice 、Omit
少 >>> 多:Required 、Record
属性:Readonly
联合类型工具
Exclude<T, U>
从类型 T 中排除 U 类型的成员
ts
// Exclude<T, U> : 从类型 T 中排除 U 类型的成员
type Status2 = "pending" | "success" | "error";
type NonError = Exclude<Status2, "error">;
NonNullable<T>
从类型 T 中排除 null 和 undefined 类型的成员,和 Exclude 类似。
ts
type MaybeString = string | null | undefined;
type StrictString = NonNullable<MaybeString>;
Extract<T, U>
从类型 T 中提取 U 类型的成员。类似于交集,但是与&交叉类型又有不同。
ts
type S1 = "a" | "b" | "c";
type S2 = "b" | "d";
type O1 = {name: string}
type O2 = {age: number}
type In2 = O1 & O2
const in2: In2 = {name: "ErMao", age: 18}
type In = S1 & S2;
type Intersection = Extract<S1, S2>;
type In3 = Extract<O1 , O2> // never
排除 : Exclude、NonNullable
交集 : Extract
函数工具
Parameters<T>
从函数类型 T 中提取参数类型的元组
ts
function fn(a: number, b: string) {}
type Args = Parameters<typeof fn>;
const valid: Args = [123, "hi"];
ReturnType<T>
获取函数返回类型
ts
function makePoint() {
return { x: 0, y: 0 };
}
type Point = ReturnType<typeof makePoint>;
const p: Point = { x: 1, y: 2 };
this 工具
ThisParameterType<T>
提取函数显式 this 参数的类型
ts
interface Person {
name: string;
}
function say(this: Person, msg: string) {
return `${this.name}: ${msg}`;
}
type ThisT = ThisParameterType<typeof say>;
OmitThisParameter<T>
移除函数显式 this 参数
ts
interface Person {
name: string;
}
function say2(this: Person, msg: string) {
return `${this.name}: ${msg}`;
}
const boundSay = say.bind({ name: "Ann" });
type FnNoThis = OmitThisParameter<typeof say2>;
const f: FnNoThis = boundSay;
ThisType<T>
为对象字面量中的 this 指定类型
ts
type ObjectDescriptor<D, M> = {
data: D;
methods: M & ThisType<D & M>
};
function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
return Object.assign({}, desc.data, desc.methods);
}
const obj = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx;
this.y += dy;
},
},
});
obj.moveBy(2, 3);
类工具
ConstructorParameters<T>
获取构造函数参数的元组类型
ts
class Box {
constructor(width: number, height?: number) {}
}
type CtorArgs = ConstructorParameters<typeof Box>;
const args: CtorArgs = [100, 50];
InstanceType<T>
获取构造函数实例的类型
ts
class UserService {
constructor(public name: string) {}
greet() {
return `Hi ${this.name}`;
}
}
type ServiceInstance = InstanceType<typeof UserService>;
const svc: ServiceInstance = new UserService("Leo");
字符串工具
Uppercase<S>
转成全大写
ts
type U = Uppercase<"hello world">
Lowercase<S>
转成全小写
ts
type L = Lowercase<"HELLO WORLD">
Capitalize<S>
将字符串的第一个字符转换为大写
ts
type Capitalized = Capitalize<"hello world">
Uncapitalize<S>
将字符串的第一个字符转换为小写
ts
type Uncapitalized = Uncapitalize<"Hello World">
Promise 工具
Awaited<T>
ts
type A = Awaited<Promise<string>>
type B = Awaited<Promise<Promise<number>>>
type C = Awaited<boolean | Promise<number>>
async function fetchNum() { return 42 }
type R = Awaited<ReturnType<typeof fetchNum>>