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

如何更新Object.defineProperty定义的JS/TS函数属性

TypeScript 场景下更新函数自定义属性方案

TypeScript编译报错来自静态类型校验:默认的Function类型定义中不存在你自定义的propertyOnFoo字段,属于类型层面的缺失,和JavaScript运行时行为无关。
你初始化属性时已经设置writable: true,JS运行时原生支持直接通过赋值修改属性值,完全不需要重复调用Object.defineProperty,直接赋值只会更新属性描述符内的value字段,不会替换整个属性描述对象。


方案1:补充函数类型定义(推荐,无运行时副作用)

通过类型合并给函数补充自定义属性的类型信息,整个逻辑仅在TS编译阶段生效,不会改动任何运行时代码,原有属性描述符会完整保留:

// 定义带自定义属性的函数类型:既符合原函数的调用签名,也携带自定义属性的类型
type FooWithCustomProp = {
  (): boolean;
  propertyOnFoo: string;
};

// 初始化函数时做类型断言,给TS补充类型信息
const foo = function () {
  return true;
} as FooWithCustomProp;

// 原有Object.defineProperty逻辑无需改动
Object.defineProperty(
  foo,
  "propertyOnFoo",
  { value: "valueOnFoo", writable: true, configurable: true }
);

// 直接赋值即可,无编译报错,运行时正常更新属性值
foo.propertyOnFoo = "updatedValue";

验证方式:赋值后调用Object.getOwnPropertyDescriptor(foo, 'propertyOnFoo')打印,可看到除value更新为新值外,writable、configurable等配置和初始定义完全一致,没有替换整个属性描述对象。

方案2:局部类型断言(适合零散访问场景)

如果不需要全局给foo补充类型,仅在修改属性的位置做局部类型断言即可,同样无运行时副作用:

// 局部断言属性类型后修改
(foo as { propertyOnFoo: string }).propertyOnFoo = "newValue";

如果不需要保留类型校验,也可以临时断言为any,但会丢失类型安全,不推荐生产环境使用:

(foo as any).propertyOnFoo = "newValue";

注意事项

  • 只有属性配置writable: false时,直接赋值才会失败(非严格模式静默失败,严格模式抛出TypeError),当前场景的配置已经满足直接赋值的条件
  • 不要通过重新调用Object.defineProperty的方式更新值,会不必要地重写属性描述符,直接赋值是性能更好、逻辑更简洁的实现方式

内容的提问来源于stack exchange,提问作者Benjamin Cai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:18:33