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

TypeScript转换带可选属性的枚举时丢失类型信息的问题

问题:带可选属性的枚举转换函数丢失类型提示

我需要创建一个支持额外选项的枚举类型,以及将其转换为对象数组的函数。但当枚举的额外选项包含可选属性时,转换后的数组元素无法正确保留该可选属性的类型提示。

原代码实现

枚举类型及定义

export type EmptyObject = Record<string, never>;
export type ReferentialEnum<Extra extends Record<string, unknown> = EmptyObject> =
  Record<string, { label: string } & Extra>;

export const statusesEnum = {
  ACTIVE: { label: "Active", color: "success.main", optional: "test" },
  DEACTIVATED: { label: "Inactive", color: "error.main" },
} satisfies ReferentialEnum<{ color: string; optional?: string }>;
export type StatusesName = keyof typeof statusesEnum;

转换函数

export function referentialEnumToReferentialCodeList<
  T extends ReferentialEnum<Record<string, unknown>>,
>(enumObj: T) {
  return Object.entries(enumObj).map(([key, stat]) => ({
    code: key as keyof T,
    ...(stat as T[keyof T]),
  }));
}

函数调用

const statusesReferential = referentialEnumToReferentialCodeList(statusesEnum);

调用后,IDE中无法访问optional这个可选属性的类型提示。

问题原因

原函数的泛型约束T extends ReferentialEnum<Record<string, unknown>>过于宽泛,TypeScript无法从这个约束中推断出Extra的具体结构(包括可选属性)。同时,map方法返回的数组类型被推断为所有枚举项类型的交集,导致可选属性被“抹平”,无法保留其可选性。

解决方案

修改泛型参数,让函数能精确捕获枚举的额外属性类型,同时明确返回类型结构:

export function referentialEnumToReferentialCodeList<
  E extends Record<string, unknown>,
  T extends ReferentialEnum<E>
>(enumObj: T): Array<{ code: keyof T } & T[keyof T]> {
  return Object.entries(enumObj).map(([key, stat]) => ({
    code: key as keyof T,
    ...stat,
  })) as Array<{ code: keyof T } & T[keyof T]>;
}

修改后,statusesReferential中的每个元素都会正确保留optional属性的可选性,IDE也能正常给出类型提示。

内容的提问来源于stack exchange,提问作者kohai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:15:08