TypeScript中如何将GraphQL生成的枚举转换为自定义DTO枚举?
GraphQL枚举转自定义DTO枚举的类型兼容问题
我需要把GraphQL Schema生成的对象类型转换为更精简的DTO类型,但在将GraphQL生成的枚举GqlPets转换为自定义枚举Pets时遇到类型兼容问题。
具体代码如下:
import type { Pets as GqlPets, GqlPerson } from 'gql/types'; enum Pets { cat = "Cat"; dog = "Dog"; }; type Person = { name: string; email: string; pet: Pets; } function gqlPersonToJson(p: GqlPerson): Person { return { name: p.name, email: p.email, pet: p.pet, //--> 错误:Type 'GqlPets' is not assignable to type 'Pets'. }; }
当我尝试如下转换方式时:
pet: GqlPerson[p.pet] as keyof typeof Pets,
出现以下错误:
TS2322: Type '"cat" | "dog"' is not assignable to type 'Pets'. Type '"cat"' is not assignable to type 'Pets'. Did you mean 'Pets.cat'?
请问我忽略了什么?
解决方案
问题根源
- 枚举类型隔离:TypeScript中即使成员值完全一致,两个不同的枚举类型也属于独立类型,
GqlPets和自定义Pets无法直接赋值。 - 转换逻辑错误:
GqlPerson是类型而非运行时值,不能用GqlPerson[p.pet]的方式取值;同时你错误地把枚举值("Cat"/"Dog")转成了枚举的键("cat"/"dog"),和Person要求的Pets枚举成员类型不匹配。 - 枚举语法错误:自定义枚举里用了分号分隔成员,正确写法应该是逗号。
正确解决方法
方法1:类型断言(简单直接)
因为GqlPets和Pets的枚举值完全对齐,可通过双重断言绕过类型检查:
function gqlPersonToJson(p: GqlPerson): Person { // 修正枚举的分号为逗号 enum Pets { cat = "Cat", dog = "Dog", }; return { name: p.name, email: p.email, pet: p.pet as unknown as Pets, }; }
方法2:基于枚举值的安全映射(更严谨)
如果想避免直接断言,可通过枚举值反向查找对应成员:
function gqlPersonToJson(p: GqlPerson): Person { enum Pets { cat = "Cat", dog = "Dog", }; // 取出GqlPets的字符串值,再映射到Pets枚举成员 const petValue = p.pet as string; const pet = Pets[petValue as keyof typeof Pets]; return { name: p.name, email: p.email, pet, }; }
关键说明
- TypeScript字符串枚举的成员本身就是字符串值,
p.pet可直接当作字符串使用。 - 只要GraphQL生成的
GqlPets和自定义Pets的枚举值完全一致,上述方法都能安全运行。
内容的提问来源于stack exchange,提问作者Avner Israel
相关产品推荐
相关产品推荐

