I am attempting to extract a specific parameter from the second parameter of a function, which is an object. From this object, I want to access the "onSuccess" function (which is optional but needed when requested), and then retrieve the first dynamic parameter of that function.
Although
Parameters<NonNullable<Parameters<typeof sampleFunction>[1]["onSuccess"]>>[0]
does work, I prefer not to use it everywhere as it can be quite difficult to read. I would like to create a more dynamic approach like: ResponseOf<typeof sampleFunction>
interface ApiCallback<T = any> {
onSuccess?: (response: T, headers?: any) => void;
onFailure?: (error: unknown) => void;
label: string;
// ...other
}
interface ApiActionPayload<T = any> extends ApiCallback<T> {
url: string;
// ... other
}
interface ApiAction<T = any> {
type: "API";
payload: ApiActionPayload<T>;
}
function apiAction<T = any>({
url = "",
label = "",
...props
}: ApiActionPayload<T>): ApiAction<T> {
return {
type: "API",
payload: {
url,
label,
...props
}
}
}
const sampleFunction = (_param1: any, callbacks: ApiCallback<{ data: any[] }>): ApiAction => {
return apiAction({
url: "google.com",
...callbacks
})
}
type DesiredNonDynamicType = Parameters<NonNullable<Parameters<typeof sampleFunction>[1]["onSuccess"]>>[0];
export type ResponseOf<
T extends (
first: any,
second: { onSuccess?: (x: any) => any; label: string;[k: string]: any },
...args: any[]
) => any> = T extends (first: any, second: { onSuccess?: (x: infer U) => any;[k: string]: any }, ...args: any[]) => any
? U : never;
type DesiredType = ResponseOf<typeof sampleFunction>;
One solution I have experimented with is:
export type ResponseOf<
T extends (
first: any,
second: { onSuccess?: (x: any) => any; label: string; [k: string]: any },
...args: any[]
) => any
= T extends (first: any, second: { onSuccess?: (x: infer U) => any; [k: string]: any }, ...args: any[]) => any
? U
: never;