Function types are contravariant for arguments and covariant for return types. How do i specify a generic function type with argument that extends Container
type without using any
in this case?
type Container<V> = {
id: string;
join: (value: V) => void;
};
const process = <V extends Container<unknown>>(processFn: (container: V) => boolean) => {
// do something with processFn
}
type ExtendedContainer = Container<number> & { status: string; };
const processFn = (container: ExtendedContainer) => {
return true;
}
process(processFn);
I understand why it errors. What i don't get is how i can express such a system without resorting to any
in processFn
type declaration for process
?
Or else, how can i make sure that the container
argument extends type Container
in general and get its type parameter?
I found a somewhat convoluted and ugly solution, using conditional types, that works:
function process<C>(processFn: C extends Container<infer _> ? (value: C) => boolean : never) {
// do something with processFn
}
process(processFn);
process((a: string) => true); // Argument of type '(a: string) => true' is not assignable to parameter of type 'never'.(2345)