Following the last question: Typescript: omit undefined/null properties from type
Using TS, I was trying to implmenet an overload for a function named request
which can accept payload
or not, by the TEndpointsPayload
(code below) (When property contain null, there is no need to pass payload),
Giving the following types:
export type TEndpointsPayload = {
getList: null, //No payload required
open: {
name: string
}
close: {
name: string
}
}
export type TEndpointsWithPayload = {
[K in keyof TEndpointsPayload as TEndpointsPayload[K] extends null ? never : K]: TEndpointsPayload[K]; //Contains the 'open' | 'close'
}; //Will create a type: {'open': {name: string}, 'close': {name: string}}
export type TEndpointsWithoutPayload = {
[K in keyof TEndpointsPayload as TEndpointsPayload[K] extends null ? K : never]: TEndpointsPayload[K]; //Contains only the 'getList'
}; //Will create a type: {'getList': null}
This is the function overload implementation
//This overload signature is not compatible with its implementation signature.ts(2394)
private async request<T extends keyof TEndpointsWithoutPayload>(endpointName: T): Promise<TEndpointsResponse[T]>;
//Code never fall into this implementation
private async request<T extends keyof TEndpointsWithPayload>(endpointName: T, payload: TEndpointsWithPayload[T]): Promise<TEndpointsResponse[T]> { ... }
Currently I'm having 2 issues, one is where the first request
function having error
This overload signature is not compatible with its implementation signature.ts(2394)
Which is solved when adding ?
to the payload
argument (but not what I'm intended to do as payload should not be optional, but required/not exist depends on the TEndpointsPayload
)
and second, is where any usage of those methods, fall to the first request
implemenmtation (aka: only allow to pass request('getList')
without a payload).
I didn't manage to have the following behavior:
request('getList')//OK
request('open', {name}) //OK
request('getList', {test}) //ERROR, no payload allow
request('open') // ERROR, payload required
Thank you! Any hint or help would be much appreciated!
Shorty after posting this question, I've come into the solution. Apparently there is need to declare both the function scenarios and the implement a third one which handle all of those. So the correct function overload will look like this:
private async request<T extends keyof TEndpointsWithoutPayload>(endpointName: T): Promise<TEndpointsResponse[T]>;
private async request<T extends keyof TEndpointsWithPayload>(endpointName: T, payload: TEndpointsWithPayload[T]): Promise<TEndpointsResponse[T]>;
private async request<T extends keyof TEndpointsPayload>(endpointName: T, payload?: TEndpointsPayload[T]): Promise<TEndpointsResponse[T]> {
//handle both scenarios
}
Hope it helps to anyone come across the same question!