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

如何在TypeScript中限制函数仅接受含访问器(getter/setter)的对象?

如何用TypeScript类型系统限制对象必须拥有访问器(getter/setter)

要实现只接受带访问器属性的对象,我们可以通过TypeScript的条件类型和泛型约束来区分普通属性与访问器属性,具体有两种常用方案:

方案一:约束指定属性为访问器

这种方案会检查你传入的属性是否为访问器,若传入普通属性则直接报错:

// 定义访问器属性的结构类型
type AccessorProperty<V> = {
  get(): V;
  set(v: V): void;
};

// 辅助类型:验证对象T的K属性是否为访问器,符合则返回原类型,否则返回never
type HasAccessor<T, K extends keyof T> = T extends Record<K, AccessorProperty<T[K]>> ? T : never;

// 修改后的函数,仅接受带有指定访问器属性的对象
function replaceUsingAccessor<
  T,
  TKey extends keyof T,
  R extends T[TKey] = T[TKey]
>(obj: HasAccessor<T, TKey>, prop: TKey, replacement: R): R {
  (obj as any)[prop] = replacement;
  return replacement;
}

测试用例

// 合法:带访问器的对象
const accessorObj = {
  get count() { return 0; },
  set count(v: number) { console.log(`设置count为${v}`); }
};
replaceUsingAccessor(accessorObj, 'count', 5); // 正常执行

// 非法:普通属性对象,会触发类型错误
const plainObj = { count: 0 };
replaceUsingAccessor(plainObj, 'count', 5); // 报错:Argument of type '{ count: number; }' is not assignable to parameter of type 'never'.

方案二:仅允许选择访问器属性作为参数

这种方案更严格,直接限制prop参数只能是对象中所有访问器属性的键,连普通属性的键都无法传入:

// 提取对象中所有属于访问器的键
type AllAccessorKeys<T> = {
  [K in keyof T]: 
    T extends { get [K](): T[K]; set [K](v: T[K]): void } ? K : never
}[keyof T];

// 修改后的函数,prop只能是访问器属性的键
function replaceUsingAccessor<
  T,
  TKey extends AllAccessorKeys<T>,
  R extends T[TKey] = T[TKey]
>(obj: T, prop: TKey, replacement: R): R {
  (obj as any)[prop] = replacement;
  return replacement;
}

测试用例

const mixedObj = {
  id: 123, // 普通属性
  get name() { return 'Alice'; }, set name(v: string) {} // 访问器属性
};

// 合法:选择访问器属性键
replaceUsingAccessor(mixedObj, 'name', 'Bob'); // 正常执行

// 非法:选择普通属性键,直接触发类型错误
replaceUsingAccessor(mixedObj, 'id', 456); // 报错:Type '"id"' is not assignable to type '"name"'.

原理说明

TypeScript中,普通属性的对象与带有访问器的对象在类型兼容性上是单向的:带访问器的对象可以赋值给普通属性类型,但普通属性对象无法赋值给要求访问器的类型。我们正是利用这一点,通过条件类型构造约束,过滤掉不符合要求的普通属性对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:33:17