TypeScript泛型'not assignable'错误:自定义对象结构赋值失败
问题分析与解决
你的代码报错的核心原因是**Winner类型的定义逻辑错误**。
错误原因拆解
- 首先,
GameNames是一个字符串联合类型:"cash3" | "cash4"。 - 当你写
type Winner<GameNames> = { [Property in keyof GameNames]: Drawing[] }时,keyof GameNames对于字符串联合类型来说,结果是string | number | symbol(所有字符串字面量的父类型都是string)。 - 这导致
Winner<GameNames>变成了一个带有索引签名的类型:{ [x: string]: Drawing[]; },要求对象的所有字符串键对应的属性都必须是Drawing[]。但你创建的{ cash3: Drawing[]; cash4: Drawing[]; }只包含两个特定键,TypeScript认为它不符合“任意字符串键都要有Drawing[]类型值”的索引签名要求,所以抛出错误。
正确解决方案
你需要让Winner类型生成一个以GameNames联合类型中的每个值为键的对象类型,有两种直接可行的方式:
方案1:使用Record工具类型
type Drawing = { date: string, draw_time: string, winning_numbers: string } // 用内置Record工具类型定义目标结构 type Winner = Record<GameNames, Drawing[]> const gameNames = { name3: 'cash3', name4: 'cash4', } as const type GameNames = (typeof gameNames)[keyof typeof gameNames] const { name3, name4 } = gameNames const winners: Winner = { [name3]: [] as Drawing[], [name4]: [] as Drawing[], }
方案2:修正自定义映射类型
如果你想自己实现映射逻辑,需要确保泛型约束指向联合类型的成员,而非联合类型的keyof结果:
type Drawing = { date: string, draw_time: string, winning_numbers: string } // 调整泛型约束,直接映射联合类型的每个成员 type Winner<K extends string | number | symbol> = { [Property in K]: Drawing[] } const gameNames = { name3: 'cash3', name4: 'cash4', } as const type GameNames = (typeof gameNames)[keyof typeof gameNames] const { name3, name4 } = gameNames const winners: Winner<GameNames> = { [name3]: [] as Drawing[], [name4]: [] as Drawing[], }
两种方案都能让TypeScript正确识别winners对象的类型,消除报错。
内容的提问来源于stack exchange,提问作者Mike S.
相关产品推荐
相关产品推荐

