TypeScript字符串枚举排序报错:枚举值与字符串类型不兼容
问题原因与解决方案
为什么会出现类型错误?
TypeScript的字符串枚举里,枚举成员(比如KEY_ENUM.DENY)是一种独立的类型,而你定义的KeyEnumValues = ${KEY_ENUM}``是把枚举成员的值转换成了字符串字面量类型("RESTRICTED_ACCESS"或"ACCES_WITH_PRIVILEGE")。这俩类型并不兼容:ORDER_OF_PRIVILEGES数组的元素类型是枚举成员类型(KEY_ENUM.ACCES/KEY_ENUM.DENY),但你传给indexOf的a.privilege是字符串字面量类型,所以TypeScript会报错。
解决方法
方法1:让排序元组的类型匹配字符串字面量
把排序元组的类型调整为KeyEnumValues的只读数组,这样indexOf就能接受字符串字面量参数:
const ORDER_OF_PRIVILEGES = [KEY_ENUM.ACCES, KEY_ENUM.DENY] as const as readonly KeyEnumValues[];
如果用TypeScript 4.9+版本,更推荐用satisfies关键字(不会丢失字面量信息,类型更安全):
const ORDER_OF_PRIVILEGES = [KEY_ENUM.ACCES, KEY_ENUM.DENY] as const satisfies readonly KeyEnumValues[];
方法2:调整User的privilege类型为枚举类型
如果后端返回的字符串可以转换成枚举成员,直接把User的privilege类型改成枚举类型:
type User = { id: number, privilege: KEY_ENUM } // 后端数据转换示例 const userFromBackend = { id: 1, privilege: "RESTRICTED_ACCESS" }; const parsedUser: User = { ...userFromBackend, privilege: KEY_ENUM[userFromBackend.privilege as keyof typeof KEY_ENUM] };
这样排序时a.privilege就是枚举成员类型,和ORDER_OF_PRIVILEGES的元素类型完全匹配,不会报错。
方法3:用const对象替代枚举(你已验证可行)
如果不想纠结枚举类型的细节,直接用const对象定义映射,它的类型天然就是字符串字面量,排序时不会有类型问题:
const KEY_ENUM = { DENY: "RESTRICTED_ACCESS", ACCES: "ACCES_WITH_PRIVILEGE", } as const; type KeyEnumValues = typeof KEY_ENUM[keyof typeof KEY_ENUM];
能否创建枚举的有序列表?
当然可以,只要保证有序列表的元素类型和你要比较的目标类型一致就行。比如方法1里把枚举值组成的元组转换成字符串字面量类型的数组,或者方法2里让目标类型是枚举成员类型,都能实现基于有序列表的排序需求。
内容的提问来源于stack exchange,提问作者Michał Sadowski
相关产品推荐
相关产品推荐

