使 TypeScript return 类型取决于是否存在可选 属性

Make TypeScript return type depend on whether optional property is present

我有一个看起来像这样的函数:

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

参数a为以下两种类型之一:

SomeType & {
    optionalProperty: string
}

// or

SomeType

我想指定 return 类型,使其与函数定义相匹配,这意味着当存在 optionalProperty 时,return 类型应该是某个 return 类型,如果不存在,它应该是不同的 return 类型。

这是我目前尝试过的方法:

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

然而,这似乎并不正确。它说该代码不可分配给该类型。

执行此操作的正确方法是什么?

您似乎想要的是overload the function。这应该以更易读的方式完成工作。

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 到 TypeScript Playground:https://tsplay.dev/wOa66m