TypeScript报错:类型‘TableNames’无法索引类型‘TState’
解决TypeScript中
TableNames无法索引TState的问题 问题重现
你的代码中,泛型函数makePagers在使用TableNames类型的键索引TState时触发了TypeScript错误:
export function makePagers< TableNames extends string, TState = Record<TableNames, INumericPageParams> >(initialState: TState) { // ... function _usePager(name: TableNames) { const { state } = usePagerState(); const pager = state[name]; // 报错:Type 'TableNames' cannot be used to index type 'TState'.ts(2536) return { numbers: { page: pager.page, per_page: pager.per_page }, strings: { page: String(pager.page), per_page: String(pager.per_page)} }; } }
错误提示显示state的类型为TState = Record<TableNames, SwapType<IPageParams, string, number>>,但TypeScript不允许用TableNames索引TState。
问题原因
虽然你给TState设置了默认类型Record<TableNames, INumericPageParams>,但TState是一个可自定义的泛型参数——用户可以传入任意类型的initialState,只要它符合TS的结构兼容性,不一定严格遵循Record<TableNames, ...>的约束。TypeScript 4.4对泛型索引的检查比较严格,不会仅凭默认类型就推断TState支持TableNames类型的键索引。
解决方案
方案1:给TState添加明确的约束
修改泛型定义,强制TState必须扩展Record<TableNames, INumericPageParams>,这样TypeScript就能确定TState的所有TableNames类型键都对应INumericPageParams类型的值:
export function makePagers< TableNames extends string, // 添加extends约束,确保TState符合Record结构 TState extends Record<TableNames, INumericPageParams> = Record<TableNames, INumericPageParams> >(initialState: TState) { // ... function _usePager(name: TableNames) { const { state } = usePagerState(); const pager = state[name]; // 不再报错 return { numbers: { page: pager.page, per_page: pager.per_page }, strings: { page: String(pager.page), per_page: String(pager.per_page)} }; } }
方案2:类型断言(仅在无法修改泛型约束时使用)
如果需要保留TState的灵活性,且你能确保传入的state一定包含TableNames类型的键,可以用类型断言绕过检查:
const pager = state[name] as INumericPageParams;
注意:这种方式会跳过TypeScript的类型检查,若后续传入的TState不符合预期,可能会引发运行时错误,所以优先选择方案1。
内容的提问来源于stack exchange,提问作者Xen_mar
相关产品推荐
相关产品推荐

