![](/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.