You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:17:29