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

如何在TypeScript中创建带条件约束的递归层级接口?

TypeScript递归条件图层接口实现方案

1. 定义基础枚举与映射类型

先明确图层组、单个图层的名称枚举,以及单个图层对应的code枚举:

// 图层名称枚举:包含组和单个图层
enum LayerName {
  // 图层组
  AG = "AG",
  OG = "OG",
  Arkaplan = "Arkaplan",
  // 单个图层
  Road = "Road",
  Building = "Building",
  Tree = "Tree"
}

// 单个图层对应的code枚举
enum RoadCode {
  MainRoad = "MAIN_ROAD",
  SideRoad = "SIDE_ROAD"
}

enum BuildingCode {
  Residential = "RESIDENTIAL",
  Commercial = "COMMERCIAL"
}

enum TreeCode {
  Pine = "PINE",
  Oak = "OAK"
}

// 映射单个图层名称到对应的code类型
type LayerCodeMap = {
  [LayerName.Road]: RoadCode;
  [LayerName.Building]: BuildingCode;
  [LayerName.Tree]: TreeCode;
};

// 提取图层组名称类型
type LayerGroupNames = LayerName.AG | LayerName.OG | LayerName.Arkaplan;
// 提取单个图层名称类型(排除所有组名)
type SingleLayerNames = Exclude<LayerName, LayerGroupNames>;

2. 实现递归条件接口

通过条件类型+映射类型,严格约束不同name对应的字段结构:

// 递归图层接口:根据name自动约束字段
type Layer = 
  // 单个图层规则:必须有对应code,禁止subLayers
  {
    [K in SingleLayerNames]: {
      name: K;
      code: LayerCodeMap[K];
      subLayers?: never;
    };
  }[SingleLayerNames]
  |
  // 图层组规则:禁止code,必须有递归的subLayers数组
  {
    [K in LayerGroupNames]: {
      name: K;
      code?: never;
      subLayers: Layer[];
    };
  }[LayerGroupNames];

3. 验证与使用示例

合法结构示例

const validLayerTree: Layer = {
  name: LayerName.AG,
  subLayers: [
    {
      name: LayerName.Road,
      code: RoadCode.MainRoad
    },
    {
      name: LayerName.OG,
      subLayers: [
        {
          name: LayerName.Building,
          code: BuildingCode.Commercial
        },
        {
          name: LayerName.Arkaplan,
          subLayers: [
            { name: LayerName.Tree, code: TreeCode.Oak }
          ]
        }
      ]
    }
  ]
};

非法结构会触发类型报错

  • 图层组添加code字段:
    // 报错:类型“{ name: LayerName.Arkaplan; code: string; subLayers: never[]; }”不能赋给类型“Layer”
    const invalidGroup: Layer = {
      name: LayerName.Arkaplan,
      code: "test",
      subLayers: []
    };
    
  • 单个图层缺少code或添加subLayers:
    // 报错:缺少属性“code”,且类型“{ name: LayerName.Tree; subLayers: never[]; }”中不存在属性“code”
    const invalidSingle: Layer = {
      name: LayerName.Tree,
      subLayers: []
    };
    

核心逻辑说明

  • 用{[K in 类型]: ...}[类型]的映射方式,为每个name值生成专属类型,确保name与code/subLayers的强绑定
  • 通过Exclude精准区分组和单个图层的名称范围
  • 用never明确禁止不符合规则的字段,让TypeScript在编写阶段就拦截错误
  • 递归的Layer类型支持任意层级的组嵌套

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:43:49