htulipe
htulipe

Reputation: 1585

Typescript, overloading a function with object argument

I have a function that takes an argument object and returns an object. The returned object will contain a "bar" key depending if the "includeBar" key is provided as an option. I tried the following overload

interface Options {
    includeBar: boolean
}

interface Return {
    foo: string;
    bar: string;
}

function someFunc(opt: Options & { includeBar: true }): Return;
function someFunc(opt: Options & { includeBar: false }): Omit<Return, "bar">;
function someFunc(opt: any): any {
    // ...
}

const { bar: bar1 } = someFunc({ includeBar: true }); // OK bar1 exists
const { bar: bar2 } = someFunc({ includeBar: false }); // OK bar2 does not exists

It works fine until I pass a declared object to myFunc:

const options: Options = {
    includeBar: true
}

const { bar } = someFunc(options); // TS Error Types of property 'includeBar' are incompatible. Type 'boolean' is not assignable to type 'false'.

Here is a sample TS playground

I saw this similar question but the answer has the same problem once the function is given a declared object.

Upvotes: 3

Views: 691

Answers (1)

cefn
cefn

Reputation: 3331

You need to make the following changes to your declaration of options...

const options = {
    includeBar: true
} as const;

Then Typescript can tell that

  1. options has a narrower type than Options
  2. options won't have had its values changed at runtime since declaration.

Upvotes: 1

Related Questions