puchm
puchm

Reputation: 167

Make TypeScript return type depend on whether optional property is present

I have a function that looks like this:

function foo(a) {
    if(a.optionalProperty === undefined) {
        return {
            one: 1,
            two: 2
        }
    } else {
        return {
            one: 1,
            two: 2,
            optionalResultProperty: "some stuff"
        }
    }
}

The parameter a is one of the following two types:

SomeType & {
    optionalProperty: string
}

// or

SomeType

I would like to specify the return type so that it matches the function definition, meaning when the optionalProperty is present, the return type should be a certain return type and if it is not present, it should be a different return type.

This is what I have tried so far:

function foo<x extends (SomeType & { optionalProperty: string }) | SomeType>(a: x): x extends (SomeType & { optionalProperty: string }) ? SomeReturnType : Omit<SomeReturnType, "optionalResultProperty"> {
    // ..
}

However, this doesn't seem to be correct. It says that the code is not assignable to the type.

What would be the correct way to do this?

Upvotes: 3

Views: 298

Answers (1)

Nishant
Nishant

Reputation: 55866

What you seem to want here is to overload the function. This should do the job in a more readable way.

type SomeType = {p: string};
type RetOne = { one: number; two: number };
type RetTwo = RetOne & { optionalResultProperty: string };

function foo(a: SomeType): RetOne;
function foo(a: SomeType & { optionalProperty: string }): RetTwo;
function foo(a: SomeType | SomeType & { optionalProperty: string }) {
  if ('optionalProperty' in a) {
    return {
      one: 1,
      two: 2,
      optionalResultProperty: "some stuff",
    };
  } else {
    return {
      one: 1,
      two: 2,
    };
  }
}

// Return type: RetOne
const ret1 = foo({p: 'some'});

// Return type: RetTwo
const ret2 = foo({p: 'some', optionalProperty: '1'});

Link to TypeScript Playground: https://tsplay.dev/wOa66m

Upvotes: 3

Related Questions