如何在TypeScript中通过映射类型移除属性并将方法Promise化
在TypeScript中通过映射类型移除对象属性并将方法Promise化
嘿,这个需求咱们用TypeScript的映射类型和条件类型就能完美解决,分两步走:先把对象里的非方法属性彻底移除,再把剩下的方法全部改成返回Promise的版本。咱们结合你的代码示例一步步来:
第一步:移除对象的非方法属性
首先得把类/对象里的方法和普通属性区分开,提取出仅包含方法的类型。你给出的JustMethodKeys和JustMethods已经是核心思路了,咱们把它补全并解释:
class A { x = 0; y = 0; visible = false; render() { return 1; } update(a: number, b: string) { return `${a}-${b}`; } } // 提取所有方法属性的键名 type JustMethodKeys<T> = { [P in keyof T]: T[P] extends Function ? P : never }[keyof T]; // 仅保留对象中的方法属性(移除所有非方法属性) type JustMethods<T> = Pick<T, JustMethodKeys<T>>; // 测试一下:JustMethods<A> 类型是 { render: () => number; update: (a: number, b: string) => string; } type TestJustMethods = JustMethods<A>;
这里JustMethodKeys通过映射类型遍历T的所有键,把方法类型对应的键保留,非方法的设为never;然后通过[keyof T]索引访问,自动过滤掉never类型的键,最终得到所有方法的键名集合。JustMethods则用Pick工具类型,只保留这些方法属性,直接移除了非方法的x、y、visible。
第二步:将方法Promise化
接下来要把这些方法的返回值都包裹成Promise。咱们需要一个能把单个函数转换成返回Promise的类型,再把它应用到整个方法集合上:
// 将单个函数转换为返回Promise的版本 type Promisified<T extends Function> = T extends (...args: infer Args) => infer R ? (...args: Args) => Promise<R> : never; // 将对象的所有方法都Promise化(先移除非方法属性,再处理方法) type PromisifiedObject<T> = { [P in keyof JustMethods<T>]: Promisified<JustMethods<T>[P]> }; // 测试一下:PromisifiedObject<A> 类型是 { render: () => Promise<number>; update: (a: number, b: string) => Promise<string>; } type TestPromisified = PromisifiedObject<A>;
这里Promisified用了条件类型的类型推断(infer):提取原函数的参数列表Args和返回值R,然后返回一个参数相同、但返回值为Promise<R>的新函数类型。
PromisifiedObject则先通过JustMethods<T>拿到仅包含方法的类型,再遍历它的每个键,把对应的方法转换成Promisified版本,最终得到一个“仅含Promise化方法”的类型。
整合起来的完整示例
把所有类型和测试代码放在一起:
class A { x = 0; y = 0; visible = false; render() { return 1; } update(a: number, b: string) { return `${a}-${b}`; } } // 提取方法键名 type JustMethodKeys<T> = { [P in keyof T]: T[P] extends Function ? P : never }[keyof T]; // 仅保留方法属性 type JustMethods<T> = Pick<T, JustMethodKeys<T>>; // 单个函数Promise化 type Promisified<T extends Function> = T extends (...args: infer Args) => infer R ? (...args: Args) => Promise<R> : never; // 移除属性并全方法Promise化的最终类型 type RemovePropsAndPromisify<T> = { [P in keyof JustMethods<T>]: Promisified<JustMethods<T>[P]> }; // 验证最终类型 type FinalType = RemovePropsAndPromisify<A>; // FinalType 等价于: // { // render: () => Promise<number>; // update: (a: number, b: string) => Promise<string>; // }
这样就完美实现了你的需求:既移除了对象的非方法属性,又把所有方法都改成了返回Promise的版本。
内容的提问来源于stack exchange,提问作者Wander Wang
相关产品推荐
相关产品推荐

