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
相关产品推荐
相关产品推荐

