提取类型中所有函数作为新的类型
ts
type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;
interface Part {
id: number;
getName(): string;
setName(name: string): void;
}
type FuncProps = FunctionProperties<Part>;
// { getName: () => string, setName(name: string) => void }理解 FunctionPropertyNames 和 FunctionProperties
这段代码定义了两个类型别名,FunctionPropertyNames 和 FunctionProperties,它们一起工作以从给定的类型中提取出所有函数属性。具体来说:
FunctionPropertyNames<T>:提取类型T中所有函数属性的键。FunctionProperties<T>:使用Pick从类型T中选取由FunctionPropertyNames<T>提取出来的函数属性。
让我们逐步拆解并理解这两个类型别名的工作原理。
1. FunctionPropertyNames<T>
typescript
type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
}[keyof T];解析
[K in keyof T]:这是一个映射类型(Mapped Type),它遍历T类型的所有键K。T[K] extends (...args: any[]) => any ? K : never:对于每个键K,检查其对应的值类型T[K]是否是函数类型(即是否可以被调用)。如果是函数,则返回键K;否则返回never。[keyof T]:这一步是索引访问类型(Indexed Access Type),它将前面映射类型的结果转换为一个联合类型,其中只包含那些通过条件检查的键。
所以,FunctionPropertyNames<T> 的作用是从 T 中提取出所有函数属性的键,并返回这些键的联合类型。
2. FunctionProperties<T>
typescript
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;解析
Pick<T, Keys>:这是 TypeScript 内置的一个工具类型,它从类型T中选取指定的键Keys,并返回一个新的类型,该类型只包含T中与Keys匹配的属性。
因此,FunctionProperties<T> 使用 Pick 来从 T 中选取由 FunctionPropertyNames<T> 提取出来的函数属性,最终返回一个新的类型,该类型只包含 T 中的函数属性。
示例解释
考虑以下接口:
typescript
interface Part {
id: number;
getName(): string;
}应用 FunctionProperties<Part>:
typescript
type FuncProps = FunctionProperties<Part>; // { getName: () => string }在这个例子中:
FunctionPropertyNames<Part>会提取出Part接口中所有函数属性的键。因为getName是唯一一个函数属性,所以结果是"getName"。FunctionProperties<Part>则使用Pick从Part中选取"getName"这个键及其对应的属性,结果是一个新类型{ getName: () => string }。
实际应用案例
假设我们有一个更复杂的对象类型,并希望从中提取所有的函数属性:
typescript
interface ComplexObject {
id: number;
name: string;
calculateTotal(...items: number[]): number;
formatName(): string;
}
type FuncPropsComplex = FunctionProperties<ComplexObject>;
// 结果类型:
// {
// calculateTotal: (...items: number[]) => number;
// formatName: () => string;
// }在这个例子中:
calculateTotal和formatName都是函数属性,因此它们会被提取出来。- 最终的
FuncPropsComplex类型只包含这两个函数属性。
总结
FunctionPropertyNames<T>:用于提取类型T中所有函数属性的键。FunctionProperties<T>:用于从类型T中选取由FunctionPropertyNames<T>提取出来的函数属性,创建一个新的类型。
这种模式非常有用,尤其是在需要对对象进行部分处理或操作时,例如仅关注对象中的方法而忽略其他属性。通过合理使用这些高级类型操作符,你可以构建更加健壮和灵活的类型系统,提高代码的安全性和可维护性。