Passing function explicit type, implicit remaining remaining args

Might be too early in the morning without my coffee, but I feel like I'm misremembering some syntax...

Here is a minimal example of what I might want to do.

interface IFoo {
    foo: string;
}

interface IBar {
    bar: string;
}

function Merge<T extends object, U extends object>(target: U, source: T): T & U {
    return Object.assign(target, source);
}


const bar: IBar = {
    bar: 'test-bar'
};

const foobar = Merge<IFoo>(bar, { foo: 'test-foo' }); // Expected 2 type arguments, but got 1.(2558)

Is there any way to accomplish the following and have bar be inferred without having to explicitly provide it?

Playground Link

Posted Sep 30, 2022, 2:46 PM UTC

24

Change Merge<IFoo>() to just Merge(), then both will be inferred:

Playground

1
FullstackVikingOP•

Right but then there’s no type safety on what you are providing to the second argument of the function. Just providing it as-is.

1

It needs IFoo attached to it somehow if you need type safety on it:

const foobar = Merge(bar, { foo: 'test-foo' } as IFoo);

you could also declare it separately if you don't like type assertions:

const foo: IFoo = { foo: 'test-foo' };
const foobar = Merge(bar, foo);

or you could just pass both generics

1
FullstackVikingOP•

Yep I get that, but it’s ugly syntax IMO. Hence why I’d prefer an approach to work with just passing in the single type argument to the function call.

It also wouldn’t work if the type is utilized in the function but transformed within the expected argument, and that mapped/transformed type isn’t exported by the library.

1