为何函数参数类型变为never?TypeScript泛型函数类型问题
TypeScript中stringify参数被推断为never的问题解决
问题根源
TypeScript无法在泛型函数中建立value参数与stringify方法参数的类型关联。虽然泛型Type约束了id是Dictionary的键,但items[id]会被推断为DictionaryItem<number> | DictionaryItem<boolean> | DictionaryItem<string>的联合类型。此时调用stringify(value)时,TypeScript无法将value的具体类型(Dictionary[Type]["value"])与联合类型中对应stringify的参数类型匹配,只能取所有stringify参数类型的交集——number & boolean & string的结果就是never,因此出现类型错误。
可行解决方案
方案1:类型断言明确关联
直接通过类型断言告诉TypeScript当前items[id]的stringify参数类型与value一致:
const update: UpdateFunction = (id, value) => { items[id].value = value; const item = items[id] as DictionaryItem<typeof value>; const stringified = item.stringify(value); console.log(stringified); };
方案2:重构泛型函数强化类型关联
调整泛型约束逻辑,让TypeScript能清晰跟踪id、value与stringify的类型绑定:
// 直接让泛型对应value的类型,同时约束id必须匹配该value类型的键 const update = <T>( id: Extract<keyof Dictionary, { [K in keyof Dictionary]: Dictionary[K]["value"] extends T ? K : never }[keyof Dictionary]>, value: T ) => { items[id].value = value; const stringified = items[id].stringify(value); console.log(stringified); };
这种写法不需要单独定义UpdateFunction类型,直接通过泛型约束保证类型安全。
方案3:类型守卫缩小范围
通过条件判断逐个缩小id的类型,让TypeScript在每个分支中明确stringify的参数类型:
const update: UpdateFunction = (id, value) => { items[id].value = value; let stringified: string | null; switch (id) { case "age": stringified = items[id].stringify(value as number); break; case "isNice": stringified = items[id].stringify(value as boolean); break; case "nickname": stringified = items[id].stringify(value as string); break; default: stringified = null; } console.log(stringified); };
该方案适合字典键数量较少的场景,类型安全但代码量会随键数量增加而增长。
内容的提问来源于stack exchange,提问作者Robo Robok
相关产品推荐
相关产品推荐

