如何用TypeScript泛型实现接口间值与键的约束?
TypeScript 接口间的约束实现方案
场景一:用 Foo 的 id 值约束 Bar 的键
要实现这类动态约束,必须借助泛型传递类型信息,普通接口无法直接依赖变量值。具体实现如下:
// 泛型 Foo,T 限定为 id 的字面量类型 interface Foo<T extends string> { id: T; } // 泛型 Bar,键必须为泛型 T 指定的类型 type Bar<T extends string> = { [K in T]: string; }; // 创建具体 Foo 实例,id 为字面量 "what" const fooObject: Foo<"what"> = { id: "what", }; // Bar 仅允许 "what" 作为键 const barObject: Bar<typeof fooObject.id> = { what: "whatever", // 合法 // wha: "whatever" // 不合法,会触发类型报错 };
核心逻辑是用泛型 T 捕获 Foo 的 id 字面量类型,再通过映射类型 [K in T] 约束 Bar 的键只能是该类型的值。
场景二:用 Bar 的键约束 Foo 的 id 类型
针对 React 场景中 Bar 包含固定属性(如 onClick)的情况,需先排除固定属性,再提取剩余键作为 Foo 的 id 可选类型:
// 定义 Bar 类型,包含任意 string/number 类型的键,以及固定 onClick 方法 type Bar = { [key: string]: string | number; onClick: () => void; }; // 泛型 Foo,id 只能是 Bar 排除 onClick 后的键类型 type Foo<T extends Bar> = { id: Exclude<keyof T, "onClick">; }; // 创建 Bar 实例,包含自定义键 "what" 和 "wha" const barObject: Bar = { what: "whatever", wha: 123, onClick: () => {}, }; // Foo 的 id 仅允许 "what" | "wha" const fooObject: Foo<typeof barObject> = { id: "what", // 合法 // id: "invalid" // 不合法,会触发类型报错 };
这里用 Exclude<keyof T, "onClick"> 过滤掉 Bar 的固定属性,只保留自定义键作为 Foo 的 id 类型范围。
内容的提问来源于stack exchange,提问作者Mark Rozovsky
相关产品推荐
相关产品推荐

