'Can TypeScript infer a function return type based on an argument in this scenario?
I'm writing a function that fetches data from an API. I know what the data will be based on the API path, so I tried an approach with 'ApiSignature' types.
I simplified the code I have at the moment:
interface Order {
id: string
}
type ApiSignature<P, D> = {
path: P,
data: D
};
type OrdersApiSignature = ApiSignature<'/orders', Order[]>
type OrderApiSignature = ApiSignature<'/order', Order>
type AnyApiSignature = OrdersApiSignature | OrderApiSignature
function useApi<T extends AnyApiSignature>(path: T['path']) {
return null as any as T['data']
}
const data = useApi('/orders') // Order | Order[]
Is it possible for TypeScript to infer that in this case the data will be Order[] and not Order, based on the function argument?
Solution 1:[1]
Building on @jcalz's comment,
But if your path is a string then you can just do this more conventionally with a key lookup like this.
type ApiSignatureMap = {
"/orders": Order[];
"/order": Order;
};
type AnyApiSignature = {
[K in keyof ApiSignatureMap]: ApiSignature<K, ApiSignatureMap[K]>;
}[keyof ApiSignatureMap];
function useApi<P extends AnyApiSignature["path"]>(path: P): ApiSignatureMap[P] { ... }
We'll use a "map" to map paths to the type of data (ApiSignatureMap).
And to get all the possible API signatures, we use a mapped type:
{
[K in keyof ApiSignatureMap]: ApiSignature<K, ApiSignatureMap[K]>;
}
This will give us an object whose values are all the API signatures we seek.
To get a union of them we can use keyof ApiSignatureMap:
{
[K in keyof ApiSignatureMap]: ApiSignature<K, ApiSignatureMap[K]>;
}[keyof ApiSignatureMap]
And finally in the function declaration, we have a generic P that can be any valid path in AnyApiSignature, then get the return type using the API signature map above.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | hittingonme |
