![](/img/trans.png)
[英]How to constrain the type of generic parameter to a Typescript function to be an enum
[英]TypeScript: Constrain generic type parameter passed to a function
我有以下通用界面( 完整的游乐场):
interface Fetcher<Params,Resp> {
fetch(params: Params): Resp;
};
它用作 function 参数,并对其通用参数应用额外的约束:
function paginateWithSearch<Params extends (PaginationParams & SearchParams),
Resp extends SomeItemsResp>(fetcher: Fetcher<Params, Resp>){
//do something
}
所有约束都用简单的对象表示,例如:
type SearchParams = {
query: string
};
棘手的部分是我不能让这个约束在实践中真正起作用:
//sample implementation with SearchParams only
const searchFetcher: Fetcher<SearchParams, SomeItemsResp> = {
fetch: function(): SomeItemsResp {
throw new Error("Function not implemented.");
}
}
//Should throw error but works ok - not extending PaginationParams
paginateWithSearch(searchFetcher);
我想出的唯一方法是用条件类型推断泛型参数并将它们手动传递给 function:
//now throws error if inferred manually
paginateWithSearch<FetcherParamsInfer<typeof searchFetcher>, FetcherRespInfer<typeof searchFetcher>>(
searchFetcher
);
我应该遗漏一些东西,因为这似乎是一个简单的问题。
虽然它可能违反直觉,但它按预期工作。
请记住,回调并非强制使用所有提供的 arguments 或其数据:
declare function convertObjToString(obj: {
toString: () => string;
}): void;
[new Date()].forEach(convertObjToString);
// Fine, even though it receives a Date with many more properties
因此,传递一个只接受SearchParams
参数的searchFetcher
是完全可以的,而它将接收一个PaginationParams & SearchParams
(即一个 object 具有比此searchFetcher
所需的更多属性)。
我们甚至可以传递一个完全不带参数的回调:
paginateWithSearch({
fetch() { // No arg at all: okay
return {
items: []
};
}
});
当然,这意味着这个回调不使用任何提供的数据,因此必然会返回不相关的响应(例如这里是一个固定的空数组)。
在您的示例中,它将返回仅与搜索相关的内容,而忽略分页参数。
由paginateWithSearch
的调用者来传递一个对这种情况有意义的回调:它是否应该与分页和搜索相关,只与其中之一相关,或者没有。
但它不能使用需要分页和搜索以外的东西的回调:例如没有排序。
paginateWithSearch({
// Error: Property 'sorting' is missing in type 'PaginationParams & SearchParams' but required in type '{ sorting: string; }'.
fetch(params: { sorting: string }) {
return { items: [] };
}
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.