You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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 | undefined does not satisfy the constraint undefined
Type TValue is not assignable to type undefined
SomeClass.ts(40, 3): This type parameter might need an extends undefined constraint.

期望效果

需要实现如下校验逻辑:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:25:10