【发布时间】:2020-12-19 22:23:18
【问题描述】:
我想实现以下推理:
type RequestAction<Data = any, TransformedData = Data> = {
type: string;
request: any | any[];
meta?: {
getData?: (data: Data, currentData: TransformedData) => TransformedData;
[extraProperty: string]: any;
};
};
function fetchBooks(
x: number,
y: string,
): RequestAction<{ raw: boolean }, { parsed: boolean }> {
return {
type: 'FETCH_BOOKS',
request: {
url: '/books',
x,
y,
},
meta: {
getData: data => ({ parsed: data.raw }),
},
};
}
const query = useQuery({
action: fetchBooks,
variables: [1, '2'], // inferred from fetchBooks argument types
});
query.data // inferred from `fetchBooks` generic
我只能同时实现一个,而不能同时实现两者。以下是我的尝试:
1)
interface QueryState<QueryStateData> {
data: QueryStateData;
error: any;
loading: boolean;
}
type Arr = readonly any[];
export function useQuery<
QueryStateData = any,
Variables extends Arr = any
>(props: {
action?: (...args: Variables) => RequestAction<any, QueryStateData>;
variables?: Variables;
}): QueryState<QueryStateData>;
这几乎可以工作,data 是从传递给 fetchBooks: RequestAction 的 QueryStateData 自动推断出来的。变量也部分起作用,但只是部分起作用。它似乎工作正常,例如如果fetchBooks 参数是(string, number),那么variables 的类型将确实是[string, number] 元组。但是由于某种原因,如果我设置了variables: [1, '1'],那么它仍然可以工作,因为突然从 TS 输入的类型将是(string | number)[],将其转换为联合数组,原因我不知道,这是不可接受的,我希望变量准确action 参数,顺序敏感。
2)
interface RequestCreator<QueryStateData> {
(...args: any[]): RequestAction<any, QueryStateData>;
}
export function useQuery<
QueryStateData = any,
R extends RequestCreator<QueryStateData> = RequestCreator<QueryStateData>
>(props: {
action?: R;
variables?: Parameters<R>;
}): QueryState<QueryStateData>;
虽然我可以通过这个实现完美的variables 推理。不幸的是,query.data 将是 any 的类型,QueryStateData 在这种情况下由于某种原因推理不起作用,它不是从 action 回调泛型中选择的。
请告诉我哪种方法更正确,以及如何调整它以同时实现variables 和data 推理。或者也许还有另一种我没有考虑过的方法。提前致谢!
【问题讨论】:
-
RequestAction是什么,fetchBooks的类型是什么?请提供minimal reproducible example。 -
我编辑了我的帖子以包含那些的简化版本。请注意,RequestAction 是类型而不是接口,因为这是 redux 操作,它也支持带有有效负载的 FSA 操作,因此我在那里使用了 union,但在这里我简化了示例
标签: typescript typescript-typings