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

如何强制函数参数匹配对象的键名与类型?

解决方案

你的写法逻辑本身是正确的,但之所以没生效,是因为I<T>是空类——TypeScript采用结构类型系统,空类的不同泛型实例会被判定为兼容(因为它们的结构完全一致),所以无法区分I<number>和I<string>。

要实现预期的类型约束,只需给I<T>添加一个带有泛型类型的私有成员,让不同泛型参数的I类型形成不兼容的名义类型:

class I<T> {
  // 添加私有泛型属性,让不同T的I实例类型不兼容
  private _marker?: T;
}

class W<T extends object> {
  field<K extends keyof T>(key: K, val: I<T[K]>) { void 0; }
}

class A {
  i: number = 3;
  s: string = "test";
}

let Winstance: W<A> = new W<A>();

Winstance.field("i", new I<number>()); // OK
Winstance.field("s", new I<number>()); // 类型错误(符合预期)
Winstance.field("i", new I<string>()); // 类型错误(符合预期)
Winstance.field("s", new I<string>()); // OK

原理说明

TypeScript对包含私有成员的类会启用名义类型检查:只有同一个类构造出来的实例,且泛型参数匹配时,才会被视为兼容类型。添加私有泛型属性_marker后,I<number>和I<string>的结构因私有成员的类型差异而不兼容,从而实现了val类型与key对应属性类型的绑定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:02:18