[英]Set generic type of a value on an object without specifying key type
我有這樣的數據結構:
const endpoints = {
async Login: (params) => { ... }
async Register: (params) => { ... }
}
現在我想指定這個 object 中的每個項目都必須接受參數 object 並返回 promise。
我可以做這樣的事情:
interface EndpointMap {
[endpointName: string]: (
params: Record<string, any>
) => Promise<any>;
}
這很好用。 但這有一個缺點。
如果我在其他地方這樣做,例如endpoint: keyof typeof endpoints
結果只會是string
。 如果我刪除EndpointMap
接口,我會得到endpoint
object 上所有鍵的字符串聯合。 好多了!
有沒有兩全其美的方法?
謝謝!
實現此目的的一種方法是不將鍵作為類型字符串定義EndpointMap
類型中的鍵:
type EndpointMap = {
[key in 'Login' | 'Register']: (
params: any
) => Promise<any>
}
const endpoints: EndpointMap = {
Login: (params) => { ... },
Register: (params) => {... }
}
// Valid
const oneKey: keyof typeof endpoints = 'Login'
// Type '"Random"' is not assignable to type '"Login" | "Register"'
const otherKey: keyof typeof endpoints = 'Random'
您可以通過使用身份 function 創建端點來實現此目的:
interface EndpointMap {
[endpointName: string]: (
params: Record<string, any>
) => Promise<any>;
}
const createEndpoints = <TMap extends EndpointMap>(map: TMap) => map;
const endpoints = createEndpoints({
login: async (params) => ({}),
register: async (params) => ({})
});
/*
type of 'endpoints' variable is:
{
login: (params: Record<string, any>) => Promise<{}>;
register: (params: Record<string, any>) => Promise<{}>;
}
*/
我們已經在泛型類型參數上聲明了帶有EndpointMap
約束的標識 function,因此 typescript 將驗證傳遞的參數是否具有適當的結構。 此外,將推斷參數類型,並且有效鍵的類型不會擴大到string
,因此:
type Keys = keyof typeof endpoints; // will be "login" | "register"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.