TypeScript:如何在字符串数组上使用 Array.includes 和可能未定义的值(可选链接)

Ric*_*Dev 7 javascript typescript

考虑这个例子:

type SomeType = {
  paymentData?: {
    paymentMethod?: string;
  }
}

const someObj: SomeType = {};

const someTest = ['creditCard', 'payPal'].includes(someObj.paymentData?.paymentMethod);
Run Code Online (Sandbox Code Playgroud)

这在 TypeScript 中不起作用,因为它推断数组元素的类型,因此string它要求与函数一起使用的值includes也是类型string,但someObj.paymentData?.paymentMethod可能是未定义的,即类型是string | undefined。我无法使用非空断言运算符 ( !),因为它无法在可选链接之后使用。

就 JavaScript 而言,如果includes使用 进行检查则完全没问题undefined,只是 TypeScript 对此不满意。有哪些好的方法可以满足 TypeScript 的需求?

Ric*_*Dev 9

一种方法是将数组转换为string | undefined. 这可能是我更喜欢的方式,因为它不会在转译的 JavaScript 代码中留下任何痕迹。此外,它仍然可以防止您意外地检查例如number实际上没有意义的 a 。

const someTest = (['creditCard', 'payPal'] as (string | undefined)[]).includes(someObj.paymentData?.paymentMethod);
Run Code Online (Sandbox Code Playgroud)

TypeScript 代码有点冗长,所以还有两个选项:

预先检查是否someObj.paymentData?.paymentMethod已定义:

const someTest = !!someObj.paymentData?.paymentMethod && ['creditCard', 'payPal'].includes(someObj.paymentData.paymentMethod);
Run Code Online (Sandbox Code Playgroud)

undefined在使用空合并运算符 ( ??)的情况下,通过回退到空字符串来确保该值始终是字符串:

const someTest = ['creditCard', 'payPal'].includes(someObj.paymentData?.paymentMethod ?? '');
Run Code Online (Sandbox Code Playgroud)

为了进一步参考,这里是 GitHub 上关于函数类型的相关线程Array.includeshttps://github.com/microsoft/TypeScript/issues/26255