'How to infer function params with object type explicitly defined
Not sure what the best wording of this was, please feel free to suggest a better title. Here's the example:
type Query = ((...params: any[]) => Promise<any>);
type Resource = {
query: Query;
}
export type Params<T> = T extends ((...params: infer R) => Promise<any>) ? R : any[];
const resource: Resource = {
query: (id: string) => Promise.resolve(id)
}
const inferredResource = {
query: (id: string) => Promise.resolve(id)
}
type ResourceParams = Params<typeof resource['query']>;
type InferredResourceParams = Params<typeof inferredResource['query']>;
The problem I have is that the first example's shape is defined by Resource, which is great because then I know what parameters are required and what shape they need to have.
But, the ResourceParams inference now doesn't work, so I can't retrieve the type of those params later on.
In the second example (inferredResource), the inference DOES work, but now I don't get the type safety of knowing the resource is of the correct shape.
Is there any way to get the best of both worlds here? I want to know the object I have is conforming to this shape, but I still want to infer its properties.
Solution 1:[1]
NB: There is a standard utility type, Parameters<>, which does what your Params does (in a slightly different way).
The problem here is a misunderstanding of where you are getting the type from. Whilst Query allows for any function returning Promise to be assigned, the actual type of Resource.query is still as per Query - i.e. any[].
With the inferred type, you get the actual supplied parameter type (string) because there is nothing else. inferredParams is still the same shape as Query (as id: string can be accepted as part of ...args: any[]), and so would be treated as having the Query interface.
Thus, ResourceParams is any[], and InferredResourceParams is id: string
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 | Dave Meehan |
