Search code examples
typescriptoptional-parametersoptional-arguments

How to set 1st arg type optionality based on other arg type in typescript


I want to create function that takes 2 curried arguments.

  • 1st arg - Could be object with specific properties (TParam) or void
  • 2nd arg - Should be object with specific properties (TParam) or object without that properties (TParam), if 1st arg type is - TParam.

Eventually i want to TParam type be passed in any argument but not twice

Here is my best 'not' working solution..

type TParam = {
    a: string;
    b: string;
}

const param: TParam = { a: "string", b: "string" };

type Check<T> = T extends TParam ? void : TParam

const example = <T extends TParam>(arg0?: T) => (arg1: Check<T>) => {
    if (typeof arg0 === 'object') {
        return arg0;
    }

    return arg1;
}

const ok = example()(param)  // Wrong
const ok1 = example(param)() // Ok

const error = example({})()  // Ok

Solution

  • You can achieve this using function overloading. The following is a working example. You can also try it out at this playground link.

    type TParam = { 
        a: string;
        b: string; 
    }
    
    const param: TParam = { a: "string", b: "string" };
    
    function example(x: TParam): () => TParam; 
    function example(): (x: TParam) => TParam; 
    function example(x?: TParam) {   
        if(x) {
            return () => x   
        }   
        else {
            return (x: TParam) => x   
        } 
    } 
    const ok = example()(param)   // No error 
    const ok1 = example(param)()  // No error 
    const error = example({})()   // Error, which is expected