I am looking for a way to define an object with two functions where one function always gets the return type of the other function as a parameter. E.g.
type DoActionArgType = { contactId: string };
type Args<T> =
{
doAction: (arg: DoActionArgType) => string; // <-- returns string
onEnd?: (arg: string) => void; // <-- takes string as the argument
}
Now I want this to work for arbitrary return types and promises, which works fine, except if I do not add the type to the function doAction
function argument.
export type $Unwrap<T> = T extends Promise<infer U>
? U
: T extends (...args: any) => Promise<infer U>
? U
: T extends (...args: any) => infer U
? U
: T;
type DoActionArgType = { contactId: string };
type Args<T> =
{
doAction: (arg: DoActionArgType) => Promise<T>;
onEnd?: (arg: $Unwrap<T>) => void;
}
function test<T>(arg: Args<T>) {}
const doAction = async ({ contactId }) => 1
test({
// doAction: async ({ contactId }: DoActionArgType) => 1, // Works
// doAction: async () => 1, // Works
// doAction, // Works
doAction: async ({ contactId }) => 1, // <--- Does not work
onEnd: (arg) => {
const a:number = arg
}
})
I assume that typescript does not understand that the function signature matches ? Because contactId
is actually typed string
just arg
of onEnd is typed as unknown
. Is there any way to make this work without adding the DoActionArgType
type to the doAction
function ?