我试图写一个函数,将返回一个对象,其键将是相同的输入数组的值:
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);
有办法做到这一点吗?
为了在第二个case中得到错误,我们需要使用泛型来知道传递了哪些特定的键。
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[])
。它实际上允许只读和可变数组。它说我们只需要读取功能。