TypeScript中约束类型不包含指定属性的标准方式?
TypeScript中如何指定类型绝对不包含特定属性?
TypeScript里没有官方内置的“标准”类型直接实现这个需求,但有比你当前写法更严谨的实现方式,能覆盖更多边缘情况。
你当前的NoValue类型虽然能拦截显式声明value属性的情况,但存在漏洞——如果类型是包含可选value的结构(比如{ value?: string }),或者通过交叉类型混入了value属性,它就无法正确拦截了。
推荐用下面这种更可靠的实现:
type NoValue<T> = T extends { value?: never } ? T : never; // 测试用例 type Foo = NoValue<{}>; // 类型检查通过 type Bar = NoValue<{ name: string }>; // 类型检查通过 type Baz = NoValue<{ value: string }>; // 报错,符合预期 type Qux = NoValue<{ value?: string }>; // 报错,成功拦截可选属性 type Quux = NoValue<{ name: string } & { value: number }>; // 报错,拦截交叉类型混入的属性
这个实现的核心是利用never类型的特性:约束传入的T必须满足value属性要么不存在,要么类型是never(也就是无法被赋值)。相比你原来的写法,它能覆盖更多场景:
- 拦截可选的
value属性,避免出现value?: undefined这种可以被赋值的情况 - 处理交叉类型的场景,确保即使通过交叉混入
value也会被拦截 - 不符合要求时直接返回
never,类型检查更严格
如果需要更通用的版本(可以指定任意禁止的属性名),可以写一个泛型工具类型:
type NoProperty<T, K extends PropertyKey> = T extends { [P in K]?: never } ? T : never; // 使用示例 type NoValue<T> = NoProperty<T, 'value'>; type Foo = NoValue<{}>; // 正常通过 type Baz = NoValue<{ value: string }>; // 报错
内容的提问来源于stack exchange,提问作者Adam B.
相关产品推荐
相关产品推荐

