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

TypeScript单属性投影函数报错:Projection类型赋值问题

解决TypeScript中project_one_property的类型错误问题

这个问题我之前也碰到过,TypeScript在这里的类型推断确实有点严格,咱们一步步拆解原因和解决方案:

为什么会报错?

你遇到的类型错误,本质是TypeScript对动态键名创建对象的类型推断规则导致的:
当你用{ [propertyName]: 1 }这种方式创建对象时,TypeScript没办法自动识别出这个对象符合Projection<T>的类型——它会默认把这个对象推断成{ [x: string]: number }(最宽泛的字符串索引类型)。而Projection<T>要求键必须是keyof T的子集,所以这两个类型不兼容,就抛出了类型错误。

三种可行的修改方案

方案1:使用类型断言(最直接)

手动告诉TypeScript,这个动态创建的对象确实符合Projection<T>的类型,用as关键字做类型断言:

const project_one_property = function<T, K extends keyof T>(object: T, propertyName: K): Partial<T> {
  // 直接断言为Projection<T>,快速解决问题
  const projection: Projection<T> = { [propertyName]: 1 } as Projection<T>;
  return project(object, projection);
};

如果想让类型更精准,也可以断言成Record<K, 1>(明确键是K类型,值为1),避免过度断言:

const projection = { [propertyName]: 1 } as Record<K, 1>;

方案2:用Object.defineProperty构建对象(更安全)

如果你不想用类型断言,也可以通过Object.defineProperty来添加属性,TypeScript能更好地跟踪键的类型:

const project_one_property = function<T, K extends keyof T>(object: T, propertyName: K): Partial<T> {
  const projection: Projection<T> = {};
  // 明确指定给projection添加的键是K类型,TypeScript能自动匹配类型
  Object.defineProperty(projection, propertyName, { value: 1 });
  return project(object, projection);
};

这种方式不需要额外断言,完全依赖TypeScript的类型推导,安全性更高。

方案3:利用TypeScript类型工具显式声明

用Pick工具类型明确指定projection的键范围,再转为Projection<T>:

const project_one_property = function<T, K extends keyof T>(object: T, propertyName: K): Partial<T> {
  // 显式声明只选取K对应的键
  const projection: Pick<Projection<T>, K> = { [propertyName]: 1 };
  return project(object, projection as Projection<T>);
};

这种方式更清晰地表达了代码意图,适合对类型严谨性要求较高的场景。

内容的提问来源于stack exchange,提问作者Shaun Xu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:22:12