One of my functions calls an API and accepts a parameter to limit the fields returned by the API:
type MaximumApiResponse = {
fieldA: string,
fieldB: number
}
const f = async <U extends keyof MaximumApiResponse>(
entity: number,
props: Array<U>
): Promise<null | Pick<MaximumApiResponse, U>> => {
return await api(entity, props);
}
I found this code snippet in the lodash source code and it works perfectly. It correctly identifies which fields the output should contain and throws a type error if you try to access a field that wasn't fetched.
However, I now want to set some default properties. I attempted this approach:
const f = async <U extends keyof MaximumApiResponse>(
entity: number,
props: Array<U> = ["fieldA"]
): Promise<null | Pick<MaximumApiResponse, U>> => {
return await api(entity, props);
}
If no second argument is provided, only fieldA
should be fetched. The expected return type would then be {fieldA: string}
. However, this leads to an error:
Type '"fieldA"' is not assignable to type 'U'.
'"fieldA"' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'keyof MaximumApiResponse'.
I also tried the following:
const f = async <U extends keyof MaximumApiResponse = "fieldA">(
entity: number,
props: Array<U> = ["fieldA"]
): Promise<null | Pick<MaximumApiResponse, U>> => {
return await api(entity, props);
}
But this resulted in the same error. Is there a way to make both versions - one with a single argument and another with two arguments - type check properly?
I came across this link, but the solution presented there seems overly complicated for my case
Please note that I am not concerned about the function being generic; I simply need a method to restrict the output properties while also providing a default option.