在打字稿中使用未定义

Using undefined in Typescript

我有以下函数定义

function getX1(): string | undefined { ... }

function getX2(): string { ... }

function myFunc(x: string | undefined): MyClass | undefined {
    if (x === undefined) return undefined;
    return { ... };
}

function consume(val: MyClass) { ... }
如果 x 未定义,

myFunc 只能保证 return 未定义。

场景 1:

const x1: string | undefined = getX1();
const res1 = myFunc(x1);
if (res1) {
    consume(res1);
}

在这里,我希望调用者在继续之前确保结果 res1 不是未定义的。

场景 2:

const x2: string = getX2();
const res2 = myFunc(x2);
consume(res2);

在这里,我不想为调用者添加相同的开销。这个片段目前给我一个编译器错误。我不知道如何在不使用 ! 的情况下避免未定义的检查。有没有办法让打字稿为我执行这条规则?

这是解决此问题的一种方法:

function myFunc(x: string): MyClass;
function myFunc(x: undefined): undefined;
function myFunc(x: string | undefined): MyClass | undefined {
  if (x === undefined) return undefined;
  return {  };
}

您可以分别定义确切的 return 类型(undefined returning undefined 和 string returning MyClass)。这有助于编译器理解当您将某个值传递给它时会发生什么。

这是一个playground link

你可以找到关于重载的解释here(感谢@jcalz 指出这一点)

LE:

理想情况下,您应该能够使用条件类型做这样的事情:

function myFunc<T extends string | undefined>(x: T): T extends string ? MyClass : undefined {
  if (x === undefined) return undefined;
  return {  };
}

不幸的是,有一个 open issue 正是关于这个问题,打字稿错误地缩小了条件类型。在这个问题被修复之前(从 4.1 开始还没有)你应该使用函数重载。

这个解决方案会起作用,只是给你一个关于如何提高打字稿可读性的提示。

使用typeof

如果您想显式检查未定义的值,请始终使用 typeof === "undefined"。在某些极端情况下,prop === undefied 无法正常工作。

避免未定义

如果您使用 undefined,您可能还想检查控制流中的空值。

首选 null 而不是未定义,它在控制流中更明确、更容易处理。

这里有一个针对您的代码示例的快速建议


function getX1(): string { ... }

function getX2(): string { ... }

function myFunc(x: string): MyClass {
    if (typeof x === "undefined") return null;
    return { ... };
}

function consume(val: MyClass) { ... }