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

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'?

请问我忽略了什么?


解决方案

问题根源

  1. 枚举类型隔离:TypeScript中即使成员值完全一致,两个不同的枚举类型也属于独立类型,GqlPets和自定义Pets无法直接赋值。
  2. 转换逻辑错误:GqlPerson是类型而非运行时值,不能用GqlPerson[p.pet]的方式取值;同时你错误地把枚举值("Cat"/"Dog")转成了枚举的键("cat"/"dog"),和Person要求的Pets枚举成员类型不匹配。
  3. 枚举语法错误:自定义枚举里用了分号分隔成员,正确写法应该是逗号。

正确解决方法

方法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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:55:29