如何实现TypeScript泛型数组元素的单独类型推断?
问题解决:无需辅助函数实现数组元素的泛型约束推断
问题分析
你当前的listOfColumns函数参数类型是Column[],TypeScript会将整个数组的元素推断为统一的泛型实例(即把所有table的类型合并为Table的联合,name合并为所有schema键的联合),导致单个元素的name无法和自身的table做精准约束。而辅助函数column是对每个元素单独做泛型推断,所以能正确校验name是否属于对应table的schema键。
解决方案
把listOfColumns改成泛型可变参数元组函数,让TypeScript对数组中的每个元素单独进行泛型推断,而不是统一合并类型:
type Table = { schema: { [column: string]: string } } type Column<T extends Table = Table, N extends keyof T['schema'] = keyof T['schema']> = { table: T, name: N } // 修改后的listOfColumns,使用泛型元组实现逐元素推断 function listOfColumns<T extends Column<any>[]>(columns: [...T]) { return columns } const t1 = { schema: { a: 'a', b: 'b' } } satisfies Table const t2 = { schema: { c: 'c', d: 'd' } } satisfies Table listOfColumns([ { table: t1, name: 'a' // ✅ 正常 }, { table: t2, name: 'c' // ✅ 正常 }, { table: t2, name: 'x' // ❌ 报错:类型'"x"'不能赋值给类型'"c" | "d"' } ])
原理说明
使用[...T]这种可变参数元组语法,会强制TypeScript逐个推断数组元素的类型,而不是将整个数组合并为单一的Column类型。这样每个元素的name都会被约束为自身table的schema键,实现和辅助函数一样的校验效果。
内容的提问来源于stack exchange,提问作者Ryan Palmer
相关产品推荐
相关产品推荐

