如何在TypeScript中用泛型结合条件类型处理多键场景?
问题描述
我有一个TypeScript函数useSome,它用泛型根据给定的单个或多个键定义params对象:
const useSome = <Keys extends string | undefined>() => { const params = {} as Keys extends string ? Record<Keys, string> : Partial<Record<string, string>>; return params; };
我希望这样使用该函数:
- 单键示例:
const { id } = useSome(); // 预期:id类型为string | undefined - 多键示例:
const { id, type } = useSome<'id' | 'type'>(); // 预期:id和type类型均为string
但传入多键泛型时,出现如下错误:
Property 'id' does not exist on type 'Record<"id", string> | Record<"type", string>'.
我的问题:
如何修改useSome函数使其正确处理多键?传递多键泛型时能否实现预期行为?
解决方案
问题根源在于原代码的条件判断逻辑:当Keys是联合类型(比如'id' | 'type')时,Keys extends string会对联合类型的每个成员单独判断,最终返回Record<'id', string> | Record<'type', string>的联合类型,而非包含所有键的Record<'id' | 'type', string>,这就导致了解构时找不到对应属性的错误。
要修复这个问题,需要让条件判断针对整个联合类型而非单个成员,调整后的代码如下:
const useSome = <Keys extends string | undefined = undefined>() => { const params = {} as [Keys] extends [undefined] ? Partial<Record<string, string>> : Record<Keys, string>; return params; };
关键逻辑说明
- 使用
[Keys] extends [undefined]而非Keys extends undefined:前者会把Keys作为一个整体进行判断,不会拆分联合类型,避免了原逻辑的分支错误。 - 默认泛型参数
= undefined:不传入泛型时,Keys自动设为undefined,返回Partial<Record<string, string>>,解构出的属性类型为string | undefined,符合单键场景预期。 - 传入联合类型时:
[Keys]与[undefined]不匹配,返回Record<Keys, string>,此时所有指定键的类型都是string,完美支持多键场景的解构需求。
验证示例
// 单键场景:id类型为string | undefined const { id } = useSome(); // 多键场景:userId和type类型均为string const { id: userId, type } = useSome<'id' | 'type'>();
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

