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

TypeScript:如何定义含保留键与任意自定义键的递归对象类型

解决带保留键的递归自定义属性TypeScript类型定义问题

问题背景

需要定义一个包含两类保留属性的类型:

  • 必填的key(类型为string | number)
  • 可选的递归children(类型为自身数组)
    其余任意自定义键的类型必须是ReactNode | ((props: IRenderDataProps) => JSX.Element)

最初尝试的接口写法直接触发类型错误:

interface IDataProps {
  [key: string]: ReactNode | ((props: IRenderDataProps) => JSX.Element) // 除以下保留键外的任意键
  key: string | number; // 保留键
  children?: IDataProps[] // 保留键
}

错误信息:TS2411: Property 'children' of type 'IDataProps[]' is not assignable to 'string' index type 'ReactNode | ((props: IRenderDataProps) => JSX.Element)'

改用交叉类型后,浅层结构可正常使用,但嵌套层级达到2层及以上时再次报错:

type TDataSource = {
  [key: string]: ReactNode | ((props: IRenderDataProps) => JSX.Element); // 除以下保留键外的任意键
} & {
  key: string | number; // 保留键
  children?: TDataSource[]; // 保留键
};

错误信息:TS2322: Type '{ key: number; name: () => JSX.Element; children: { key: number; name: () => JSX.Element; }[]; }' is not assignable to type 'TDataSource'...Property 'children' is incompatible with index signature.

错误原因

TypeScript的索引签名要求所有属性类型必须与索引签名类型兼容。不管是直接接口声明还是交叉类型,children的TDataSource[]类型都无法匹配索引签名定义的ReactNode | ((props: IRenderDataProps) => JSX.Element),嵌套场景下这个类型冲突会被直接触发。

正确解决方案

通过映射类型+排除保留键的组合方式,结合显式声明保留属性,可完美解决该问题:

import type { ReactNode, JSX } from 'react';

// 渲染props类型,根据业务需求补充字段
interface IRenderDataProps {
  // 自定义渲染参数
}

type TDataSource = {
  key: string | number;
  children?: TDataSource[];
} & {
  [K in Exclude<string, 'key' | 'children'>]: ReactNode | ((props: IRenderDataProps) => JSX.Element);
};

原理说明

  • 显式声明key和children两个保留属性,它们的类型不受后续映射类型约束
  • 使用Exclude<string, 'key' | 'children'>确保映射类型仅作用于除保留键外的所有字符串键
  • 映射类型强制要求所有非保留键的类型必须为ReactNode或返回JSX元素的函数

验证示例

嵌套结构可正常通过类型校验:

const nestingExample: TDataSource[] = [
  {
    key: 5,
    [`custom-key-demo`]: () => <>SomeJSX</>,
    children: [
      {
        key: 6,
        anotherCustomKey: '这是ReactNode类型的字符串'
      }
    ],
  },
];

该方案既满足保留键的类型要求,也约束了自定义键的类型,同时支持无限层级的嵌套结构,不会触发类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:45:35