我正在尝试编写一个函数,该函数将返回一个对象,该对象的键将与输入数组的值相同:
type PathParam = 'userId' | 'groupId' | 'commentId';
function usePathParams(params: PathParam[]) {
return params.reduce(
(acc, param) => ({ ...acc, [param]: 'whatever' }),
{} as Record<typeof params[number], string>,
);
}
// OK
const { userId } = usePathParams(['userId', 'commentId']);
// Should be an error but is not
const { userId, groupId } = usePathParams(['userId', 'commentId']);
// Passing a tuple doesn't seem to work either
const { userId, groupId } = usePathParams(['userId', 'commentId'] as const);
有什么办法可以实现吗?
答案 0 :(得分:1)
为了在第二种情况下出错,我们需要使用泛型来了解传递了哪些特定键。
function usePathParams<Params extends PathParam>(params: Params[]) {
return params.reduce(
(acc, param) => ({ ...acc, [param]: 'whatever' }),
{} as Record<Params, string>,
);
}
我们现在得到所需的错误 属性 groupId
不存在于类型 Record<"userId" | "commentId", string>
您的第三个示例仍然有错误,因为 as const
使元组 readonly
。如果您想支持这一点,您可以将函数参数更改为 (params: readonly Params[])
。这实际上允许只读和可变数组。它说我们只需要读取功能。