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

如何在TypeScript中将导入JSON的字符串属性映射为枚举类型

问题描述

假设我有如下JSON数据:

[
  { "type": "one", "tile": { "x": 0, "y": 0 }},
  { "type": "two", "tile": null }
]

将其导入TypeScript模块:

import dataJson from "data.json";

若定义类型type T = typeof dataJson;,则T会被推断为:

type T = ({
  type: string;
  tile: {
    x: number;
    y: number;
  };
} | {
  type: string;
  tile: null;
})[]

但我期望将其类型定义为:

enum Type {
  one,
  two
}

interface Entry {
  type: Type,
  tile: {
    x: number,
    y: number
  } | null
}

const data: Entry[] = dataJson;

此时TypeScript会报错:

Types of property 'type' are incompatible.
Type 'string' is not assignable to type 'FeatureType'. ts(2322)

我清楚报错原因,但不知如何解决,请问能否将自动生成的typeof dataJson类型转换为Entry类型?


解决方案

方法1:直接使用类型断言

如果能确定JSON数据完全符合Entry结构,直接用类型断言告诉TypeScript数据的真实类型:

// 基础断言
const data = dataJson as Entry[];

// 更严格的双重断言(当基础断言不生效时使用)
const data = dataJson as unknown as Entry[];

方法2:添加运行时类型守卫校验

如果需要确保数据合法性,写一个类型守卫函数,在运行时验证每个条目是否符合Entry规范,同时让TypeScript认可类型转换:

function isEntry(item: unknown): item is Entry {
  if (typeof item !== 'object' || item === null) return false;
  const entry = item as Entry;
  // 验证type是否属于Type枚举的有效值,同时校验tile的结构
  return Object.values(Type).includes(entry.type as Type) && 
    (
      entry.tile === null || 
      (typeof entry.tile === 'object' && typeof (entry.tile as any).x === 'number' && typeof (entry.tile as any).y === 'number')
    );
}

// 过滤合法数据并转换类型
const data = dataJson.filter(isEntry) as Entry[];

方法3:让TypeScript推断更精确的JSON类型

修改JSON导入方式,让TS把JSON中的字符串推断为字面量类型而非宽泛的string(需要TypeScript 5.0+):
首先确保tsconfig.json中开启resolveJsonModule和esModuleInterop,然后导入时添加类型断言:

import dataJson from "./data.json" assert { type: "json" };

同时将枚举改为字符串枚举,和JSON中的值匹配:

enum Type {
  one = "one",
  two = "two"
}

interface Entry {
  type: Type;
  tile: { x: number; y: number } | null;
}

// 此时TS可自动匹配类型,无需额外断言
const data: Entry[] = dataJson;

方法4:基于原有推断类型做映射转换

如果不想修改枚举或导入方式,可以基于typeof dataJson定义转换后的类型:

type InferEntry = typeof dataJson[number] & {
  type: Type;
};

const data = dataJson as InferEntry[];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:18:09