Could the Tuple spreading syntax in Typescript be utilized to consolidate these function overloads? The challenge lies in the necessity to refactor the function arguments into new types.
type Type = TString | TNumber
type TString = { tag: 'string' }
type TNumber = { tag: 'number' }
interface Mapping {
string: string
number: number
}
type Remap<T extends Type> = Mapping[T['tag']];
// Is it possible to merge these function overloads into one?
function checkFn<R extends Type, A extends Type, B extends Type, C extends Type>(argTypes: [A, B, C], retType: R, fn: (arg0: Remap<A>, arg1: Remap<B>, arg2: Remap<C>) => Remap<R>): void;
function checkFn<R extends Type, A extends Type, B extends Type>(argTypes: [A, B], retType: R, fn: (arg0: Remap<A>, arg1: Remap<B>) => Remap<R>): void;
function checkFn<R extends Type, A extends Type>(argTypes: [A], retType: R, fn: (arg: Remap<A>) => Remap<R>): void;
function checkFn(argTypes: any[], retType: any, fn: any): void {}
const stringType: TString = { tag: 'string' }
const numberType: TNumber = { tag: 'number' }
checkFn([numberType, stringType, numberType], numberType, (arg0, arg1, arg2) => 42)