如何实现ILoadedValue仅接受含undefined的类型并触发编译报错?
问题:约束
ILoadedValue仅接受包含undefined的类型 需求说明
我定义了ILoadedValue<TValue>类型,作为可包含undefined的类型的包装器,但要禁止传入不包含undefined的TValue——这类场景直接用undefined表示加载中更高效。
当前实现的问题
我原本用TValue extends undefined做约束:
/** * ILoadedValue 用于为可能为 undefined 的值提供原子化的加载状态信息, * 使用方式应为 `ILoadedValue<TValue> | undefined` * * 注意:当 TValue 不可能为 undefined 时请避免使用此类型, * 这种场景下直接用 undefined 表示加载中更高效 */ export interface ILoadedValue<TValue extends undefined> { value: TValue; }
但在如下类中使用时会报错:
export class SomeClass<TValue> { loadedValue: ILoadedValue<TValue | undefined> | undefined; }
错误信息:
TS2344: Type
TValue | undefineddoes not satisfy the constraintundefined
TypeTValueis not assignable to typeundefined
SomeClass.ts(40, 3): This type parameter might need an extendsundefinedconstraint.
期望效果
需要实现如下校验逻辑:
export class SomeClass<TValue> { // 合法:TValue | undefined 包含 undefined loadedValue: ILoadedValue<TValue | undefined> | undefined; } export class SomeClass2<TValue> { // 报错:TValue 不保证包含 undefined loadedValue: ILoadedValue<TValue> | undefined; }
解决方案
可以通过条件类型+泛型约束实现需求,要求TValue必须包含undefined作为成员类型:
方案1:抽离判断类型
// 定义辅助类型,判断T是否包含undefined type IsUndefinedIncluded<T> = undefined extends T ? T : never; /** * ILoadedValue 用于为可能为 undefined 的值提供原子化的加载状态信息, * 使用方式应为 `ILoadedValue<TValue> | undefined` * * 注意:当 TValue 不可能为 undefined 时请避免使用此类型, * 这种场景下直接用 undefined 表示加载中更高效 */ export interface ILoadedValue<TValue extends IsUndefinedIncluded<TValue>> { value: TValue; }
方案2:直接内联判断
/** * ILoadedValue 用于为可能为 undefined 的值提供原子化的加载状态信息, * 使用方式应为 `ILoadedValue<TValue> | undefined` * * 注意:当 TValue 不可能为 undefined 时请避免使用此类型, * 这种场景下直接用 undefined 表示加载中更高效 */ export interface ILoadedValue<TValue extends (undefined extends TValue ? unknown : never)> { value: TValue; }
原理说明
- 当
TValue包含undefined时(比如string | undefined),undefined extends TValue返回true,约束等价于TValue extends unknown,无实际限制,类型合法。 - 当
TValue不包含undefined时(比如string),undefined extends TValue返回false,约束等价于TValue extends never,除never本身外的任何类型都无法满足此约束,触发编译错误。
内容的提问来源于stack exchange,提问作者Ivan Ivanyuk
相关产品推荐
相关产品推荐

