如何定义TS泛型类型,实现数组元素属性与对象的匹配校验
解决方案
要实现这种类型约束,你可以通过泛型类型定义或辅助泛型函数让TypeScript精确检查每个子数组的属性匹配关系,以下是两种可行方式:
方式一:直接定义泛型数组类型
首先定义一个泛型类型ValidEntry<T>,用来约束单个子数组的结构:
type ValidEntry<T> = [T, Array<keyof T>];
接着给数组指定类型为ValidEntry<typeof a> | ValidEntry<typeof b>的数组:
const a = { propA: 'hello' } const b = { propB: 'world' } const arr: Array<ValidEntry<typeof a> | ValidEntry<typeof b>> = [ [a, ["propA"]], // ✅ 合法 [b, ["propB"]], // ✅ 合法 // [a, ["propB"]], // ❌ 报错:"propB"不属于typeof a的属性 // [a, ["propC"]], // ❌ 报错:"propC"不属于typeof a的属性 // [b, ["propA"]], // ❌ 报错:"propA"不属于typeof b的属性 ];
这种方式直接通过类型约束实现检查,但如果数组元素类型较多,联合类型会变得冗长。
方式二:使用辅助泛型函数(更灵活)
如果需要更灵活的类型推导,尤其是当数组元素类型不确定时,可以写一个辅助函数让TypeScript自动推导每个子元素的类型:
const a = { propA: 'hello' } const b = { propB: 'world' } function createValidEntries<T extends unknown[]>( ...entries: { [K in keyof T]: [T[K], Array<keyof T[K]>] } ) { return entries; } // 正确用法 const arr = createValidEntries( [a, ["propA"]], [b, ["propB"]] ); // 错误用法会直接触发类型报错 // const invalidArr = createValidEntries( // [a, ["propB"]], // ❌ "propB"不是a的属性 // [b, ["propD"]] // ❌ "propD"不是b的属性 // );
这个函数的核心是利用映射类型,让每个传入的子数组都满足「第二个元素是第一个元素对象的属性数组」的约束,TypeScript会自动为每个子元素做独立的类型检查。
内容的提问来源于stack exchange,提问作者Jeon
相关产品推荐
相关产品推荐

