我想做一个泛型钩子,它接受useQuery
作为参数并处理分页。
这意味着我的trpc查询将始终提供skip
和take
参数。它总是在响应中返回一个count
和一个items
数组。
function usePagination(query){
const [skip, take] = useSomethingThatManagesThis();
const response = query.useQuery({
skip,
take,
});
return useMemo(() => ({
items: response.data?.items,
count: response.data?.count
}), [response]);
}
function MyComponent() {
const paginated = usePagination(api.user.list);
const firstUserEmail = paginated.items?.[0].email;
}
它在vanilla JavaScript中工作,但我很难正确输入它。
我试图简单地重用trpc客户端类型,但我无法区分请求类型(take,query)和响应类型(items)。
import {
AnyProcedure,
AnyQueryProcedure,
inferProcedureOutput,
} from "@trpc/server";
interface BaseInput {
skip: number;
take: number;
}
type UseDatatableArgs<TData extends AnyQueryProcedure> = {
query?: {
useQuery: (input: BaseInput) => ProcedureUseQuery<
{ count: number } & AnyProcedure,
string
> & {
data: {
count: number;
items: inferProcedureOutput<TData>;
};
};
};
};
function usePagination<TData extends AnyQueryProcedure>(query){
const [skip, take] = useSomethingThatManagesThis();
const response = query.useQuery({
skip,
take,
});
return useMemo(() => ({
items: response.data?.items,
count: response.data?.count
}), [response]);
}
但是我没有在响应中输入任何项目
function MyComponent() {
const paginated = usePagination(api.user.list);
const firstUserEmail = paginated.items?.[0].email; // paginated.items is any
}
我目前有一个变通方案,使用TRPC提供的类型推断实用程序,但我喜欢从查询中扣除这一点
export type RouterOutputs = inferRouterOutputs<AppRouter>;
function MyComponent() {
const paginated = usePagination<RouterOutputs["user"]["list"]>(api.user.list);
const firstUserEmail = paginated.items?.[0].email;
}
1条答案
按热度按时间3phpmpom1#
您可以使用TypeScript的泛型类型推断和条件类型。也从@trpc服务器导入
ProcedureType
这里的
ProcedureType
type表示TRPC过程的类型(查询、变异等)。UseDatatableArgs类型将接受一个表示过程类型的泛型参数TData
,它需要一个查询属性,该属性具有一个useQuery
函数,该函数接受BaseInput
作为输入,并返回一个ProcedureUseQuery类型和响应类型{ count: number } & TData
。这是一份经过编辑的代码副本