Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript, overloading a function with object argument

Tags:

typescript

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.

like image 986
htulipe Avatar asked Sep 12 '26 14:09

htulipe


1 Answers

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.
like image 145
cefn Avatar answered Sep 16 '26 19:09

cefn