如何在TypeScript中实现含特定属性的映射类型?
TypeScript实现排除特定键的动态属性+固定属性类型
你的需求完全可以实现,原代码的问题在于虽然通过条件类型排除了K为"isDirty"的情况,但TS并没有在索引签名阶段自动识别K绝不会是"isDirty",导致类型约束不够严谨。下面是两种更可靠的实现方式:
方案一:直接约束K的范围(推荐)
通过Exclude<string, "isDirty">直接限定K只能是除"isDirty"外的字符串类型,再用交叉类型合并动态属性和固定的isDirty属性:
type Foo<T, K extends Exclude<string, "isDirty">> = { [P in K]: T; } & { isDirty: boolean };
使用示例
// 正常通过类型检查 const foo: Foo<number, "bar"> = { bar: 5, isDirty: false }; const potatoes: Foo<number[], "potatoes"> = { potatoes: [1, 6, 15], isDirty: false }; // 若尝试传入"isDirty"作为K,TS会直接报错:类型'"isDirty"'不满足约束'Exclude<string, "isDirty">' // const invalid: Foo<number, "isDirty"> = { isDirty: false };
这种方式最直观,从根源上禁止了K取"isDirty"的可能,TS的类型推断也更清晰。
方案二:通过条件类型映射所有键
如果偏好单对象类型而非交叉类型,可以把K和"isDirty"合并成联合键,再通过条件类型分配对应属性的类型:
type Foo<T, K extends string> = K extends "isDirty" ? never : { [P in K | "isDirty"]: P extends "isDirty" ? boolean : T; };
这种方式同样能实现需求,当K为"isDirty"时返回never类型,直接阻止该情况的使用。
内容的提问来源于stack exchange,提问作者LoyalPotato
相关产品推荐
相关产品推荐

