如何在TypeScript中创建含全量/无额外属性的约束类型
实现TypeScript类型:额外属性必须全有或全无
需求:基于BaseProps和ExtraProps创建类型,要求ExtraProps的所有属性要么全部存在,要么完全不存在——不能只添加其中某一个额外属性。
初始尝试(存在问题)
用户最初的写法无法达到预期的报错效果:
type BaseProps = { prop1: string; prop2: number; }; type ExtraProps = { extraPropA: boolean; extraPropB: string; }; // 这个类型无法阻止仅添加部分ExtraProps属性的情况 type MyType = BaseProps | (BaseProps & ExtraProps);
因为TypeScript的联合类型检查是宽松的,只要对象匹配其中一个分支(比如BaseProps)就会通过,多余的属性会被忽略,导致仅添加部分额外属性的对象不会触发报错。
正确的类型实现
通过交叉类型结合never类型来严格限制:
type BaseProps = { prop1: string; prop2: number; }; type ExtraProps = { extraPropA: boolean; extraPropB: string; }; type MyType = // 仅保留BaseProps,禁止任何ExtraProps的属性存在 (BaseProps & { [K in keyof ExtraProps]?: never }) | // 同时包含BaseProps和所有ExtraProps属性 (BaseProps & ExtraProps);
使用验证
// ❌ 报错:extraPropB存在但缺少extraPropA,不符合任何一个分支 const obj1: MyType = { prop1: "value1", prop2: 42, extraPropB: "someValue" }; // ❌ 报错:extraPropA存在但缺少extraPropB,不符合任何一个分支 const obj2: MyType = { prop1: "value2", prop2: 55, extraPropA: true }; // ✅ 合法:仅包含BaseProps属性 const obj3: MyType = { prop1: "value3", prop2: 12 }; // ✅ 合法:包含所有BaseProps和ExtraProps属性 const obj4: MyType = { prop1: "value4", prop2: 555, extraPropA: true, extraPropB: "someValue" };
原理说明
- 第一个分支
BaseProps & { [K in keyof ExtraProps]?: never }:要求所有ExtraProps的属性要么不存在,要么类型为never(即无法赋值),保证不会出现部分额外属性。 - 第二个分支
BaseProps & ExtraProps:要求必须包含所有ExtraProps的属性。 - 这样任何仅包含部分
ExtraProps属性的对象都无法匹配任意一个分支,从而触发TypeScript类型错误。
内容的提问来源于stack exchange,提问作者Ofir
相关产品推荐
相关产品推荐

