I wrap my api request to an obj with moduleName and apiName with url values like
const modules = {
cart: {
cart: '/shoppingCart',
goodsSkus: '/shoppingCart/goodsSkus',
},
}
And i use a helperFunction
below to convert it to my apiActionObject
now this is from from js file, because my ts file is on error.
let apiAction = {};
Object.keys(modules).forEach((modulesName) => {
apiAction[modulesName] = {};
Object.keys(modules[modulesName]).forEach((apiName) => {
apiAction[modulesName][apiName] = async ({
method = 'get',
id,
resource,
...options
} = {}) => {
let url = modules[modulesName][apiName];
url += `${id !== undefined ? `/${id}` : ''}${
resource ? `/${resource}` : ''
}`;
return service({ url, method, ...options });
};
});
});
And i try to make my ApiAction type using code below, everythink looks well.
type ModuleName = keyof typeof modules;
type ApiName<T extends ModuleName> = keyof typeof modules[T];
type ApiAction = {
[moduleName in ModuleName]: {
[apiName in ApiName<moduleName>]: (
arg: ApiServiceParams<any, any>
) => Promise<any>;
};
};
Then i try to add some more specific type in ApiServiceParams, below code goes wrong
// requestAndResponseType
type _RRType = {
[moduleName in ModuleName]: {
[apiName in ApiName<moduleName>]: {
req: any;
res: any;
};
};
};
interface RRType extends _RRType {
cart: {
cart: {
req: Api.GetPvStatsUsingGetParams;
res: Api.AfterSaleTicketPageResponse;
};
goodsSkus: {
req: Api.GetPvStatsUsingGetParams;
res: Api.AfterSaleTicketPageResponse;
};
};
}
type TypeWorksFine = RRType['goods']['product']['req']; // type is any
type TypeWorksFine2 = RRType['cart']['goodsSkus']['req']; // type is Api.GetPvStatsUsingGetParams;
// https://stackoverflow.com/questions/46846669/type-key-cannot-be-used-to-index-type-object
type ApiAction = {
[moduleName in ModuleName]: {
[apiName in keyof RRType[moduleName]]: (
arg: ApiServiceParams<RRType[moduleName][apiName]['req'], any>
) => Promise<any>;
};
};
The code above is both type TypeWorksFine
and TypeWorksFine2
works properly, but in the interation of ApiAction, it fails with error Type '"req"' cannot be used to index type 'RRType[moduleName][apiName]'.
In fact i first ran into this error when i use the key as [apiName in ApiName] as below
type ApiAction = {
[moduleName in ModuleName]: {
[apiName in ApiName<moduleName>]: (
arg: ApiServiceParams<RRType[moduleName][apiName], any> // Type 'apiName' cannot be used to index type 'RRType[moduleName]'
) => Promise<any>;
};
};
then i found a tip to fix this type key cannnot be used to index type object answer to solve this problem. but when i get in this problem by the req
property, i can't find a way to fix.
So there is a way to iterate the type object and make the new type? Thank you in advance!
Via Active questions tagged javascript - Stack Overflow https://ift.tt/tdmiCHS
Comments
Post a Comment