如何基于TableHeader接口数组的key值类型定义TableData接口?
如何基于TableHeader数组的key约束TableData的键类型?
要实现这个需求,核心是让TypeScript保留tableHeaders中每个key的具体字面量类型,然后通过映射类型动态生成TableData的结构。直接用TableHeader[]定义tableHeaders的话,TypeScript会把key推断成宽泛的string,没法实现精确约束,所以得做以下几步:
步骤1:让tableHeaders保留key的字面量类型
首先,我们需要让tableHeaders的每个key被推断为具体的字符串字面量(比如'index'、'firstName'),而不是通用的string。最简单的方式是用as const断言:
interface TableHeader { key: string; value: string; } // 用as const让TypeScript保留每个key的字面量类型 const tableHeaders = [ { key: 'index', value: 'Index' }, { key: 'firstName', value: 'First Name' }, { key: 'lastName', value: 'Last Name' } ] as const;
如果你想严格遵循TableHeader接口的约束,也可以用一个泛型函数来创建tableHeaders,同时保留字面量类型:
interface TableHeader { key: string; value: string; } // 泛型函数确保headers符合TableHeader类型,同时推导key的字面量 function createTableHeaders<Keys extends string>( headers: readonly ({ key: Keys; value: string })[] ) { return headers; } const tableHeaders = createTableHeaders([ { key: 'index', value: 'Index' }, { key: 'firstName', value: 'First Name' }, { key: 'lastName', value: 'Last Name' } ] as const);
步骤2:定义动态的TableData类型
接下来,我们定义一个泛型TableData类型,它接收tableHeaders的类型作为参数,然后通过映射类型生成对应的键结构:
// 从Headers数组类型中提取所有key的联合类型,生成对应的对象类型 type TableData<Headers extends readonly TableHeader[]> = { // Headers[number]取出数组中每个元素的类型,['key']提取key的字面量 [K in Headers[number]['key']]: string; // 值类型可以根据需求改成string | number等 };
步骤3:使用TableData约束数据数组
现在就可以用TableData<typeof tableHeaders>来约束你的tableData数组了,TypeScript会自动检查每个对象是否包含所有必需的key:
const tableData: TableData<typeof tableHeaders>[] = [ { index: '1', firstName: 'John', lastName: 'Doe' }, { index: '2', firstName: 'Jane', lastName: 'Smith' } ]; // 如果少写某个key,TypeScript会直接报错: // const badData: TableData<typeof tableHeaders>[] = [ // { index: '3', firstName: 'Bob' } // 报错:缺少属性'lastName' // ];
原理说明
as const断言会把数组和内部对象转换成只读的字面量类型,让TypeScript记住每个key的具体值,而不是把它们当成通用的string。Headers[number]是TypeScript的索引访问类型,用来取出数组类型中所有元素的联合类型。- 映射类型
[K in ...]会遍历所有key的字面量,生成对应的对象属性,从而实现动态的类型约束。
这样一来,当你修改tableHeaders中的key时,TableData的类型会自动更新,不需要手动修改类型定义,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Hadi KAR
相关产品推荐
相关产品推荐

