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

如何为嵌套JSON生成TypeScript类型?卢旺达数据场景求助

卢旺达行政区划TypeScript类型定义及性能疑问

我有一套卢旺达省级行政区划的JSON数据,结构如下:

{
  "East": {...},
  "West": {...},
  "North": {...},
  "South": {...},
  "Kigali": {...}
}

每个省份对应的对象包含多个地区,示例:

{
  "East": {
    "Nyagatare": {...},
    "Gatsibo": {...},
    "Kayonza": {...},
    {...}
  }
}

完整的层级结构为:

Rwanda -> Province -> District -> Sector -> Cell -> Village

部分数据示例:

{
  "East": {
    "Bugesera": {
      "Gashora": {
        "Biryogo": [
          "Bidudu",
          "Biryogo",
          "Buhoro",
          "Gihanama",
          "Kagarama",
          "Kanyonyomba",
          "Karutete",
          "Kivugiza",
          "Rugunga"
        ],
        "Kabuye": [
          "Bidudu",
          "Kabuye",
          "Karizinge",
          "Rwagasiga",
          "Rweteto"
        ]
      }
    }
  }
}

目前我只能定义到District层级的类型,代码如下:

import rwanda from "~/constants/rwanda.json";

// 该模块导出处理国家数据所需的类型和函数
// rwanda是来自json文件的国家数据
// 结构为:Record<Province, Record<District, Record<Cell, Record<Village>>>>

type Rwanda = typeof rwanda;
type Province = keyof Rwanda;
type District = keyof {
  [province in Province as keyof Rwanda[province]]: "hello";
};

我的需求是:

  1. 为上述所有层级的行政区划生成对应的TypeScript类型
  2. 咨询生成大量这类类型是否会带来性能损耗

完整层级TypeScript类型定义

你可以通过嵌套的映射类型,逐步推导每个层级的类型,同时还能定义关联层级的类型(比如某省份下的专属地区列表):

import rwanda from "~/constants/rwanda.json";

type Rwanda = typeof rwanda;

// 省份类型:所有省份名称的联合类型
type Province = keyof Rwanda;

// 某省份对应的地区类型(精确关联)
type DistrictOfProvince<P extends Province> = keyof Rwanda[P];

// 所有地区类型(跨省份的联合类型)
type District = DistrictOfProvince<Province>;

// 某省份+地区对应的分区类型(精确关联)
type SectorOfDistrict<P extends Province, D extends DistrictOfProvince<P>> = keyof Rwanda[P][D];

// 所有分区类型(跨层级的联合类型)
type Sector = {
  [P in Province]: {
    [D in DistrictOfProvince<P>]: SectorOfDistrict<P, D>;
  }[DistrictOfProvince<P>];
}[Province];

// 某省份+地区+分区对应的小区类型(精确关联)
type CellOfSector<P extends Province, D extends DistrictOfProvince<P>, S extends SectorOfDistrict<P, D>> = keyof Rwanda[P][D][S];

// 所有小区类型(跨层级的联合类型)
type Cell = {
  [P in Province]: {
    [D in DistrictOfProvince<P>]: {
      [S in SectorOfDistrict<P, D>]: CellOfSector<P, D, S>;
    }[SectorOfDistrict<P, D>];
  }[DistrictOfProvince<P>];
}[Province];

// 某省份+地区+分区+小区对应的村庄类型(精确关联)
type VillageOfCell<P extends Province, D extends DistrictOfProvince<P>, S extends SectorOfDistrict<P, D>, C extends CellOfSector<P, D, S>> = Rwanda[P][D][S][C][number];

// 所有村庄类型(跨层级的联合类型)
type Village = {
  [P in Province]: {
    [D in DistrictOfProvince<P>]: {
      [S in SectorOfDistrict<P, D>]: {
        [C in CellOfSector<P, D, S>]: VillageOfCell<P, D, S, C>;
      }[CellOfSector<P, D, S>];
    }[SectorOfDistrict<P, D>];
  }[DistrictOfProvince<P>];
}[Province];

类型说明

  • 基础类型(Province/District等):覆盖所有对应层级名称的联合类型,适用于不限制上级层级的场景
  • 关联类型(DistrictOfProvince/SectorOfDistrict等):在已知上级层级的情况下,返回更精确的下级类型,比如DistrictOfProvince<'East'>只会包含东部省的所有地区

性能损耗问题

TypeScript处理这类类型推导确实存在理论上的性能影响,但针对卢旺达的行政区划规模,实际可以忽略,具体分析:

  1. 数据规模:卢旺达的行政区划总层级数量有限(5个省份,下级层级总数在数千级别),这种规模的类型推导对现代TypeScript编译器完全在可承受范围内。
  2. 编译机制:TypeScript会缓存已推导的类型,重复使用相同类型时不会重复计算,只有首次编译或类型定义修改时才会重新推导。
  3. 使用场景:如果只是定义类型用于类型校验,不进行复杂的嵌套条件运算或递归类型操作,基本不会感受到编译速度差异。

如果后续确实遇到编译变慢的情况,可以尝试优化:

  • 将类型定义拆分到单独模块,避免和业务代码混编
  • 对于不需要精确校验的场景,用type Province = string这类简单类型替代联合类型(但会失去精确校验的优势)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 10:18:18