【问题标题】:TypeScript: How to use Array.includes with possibly undefined value (optional chaining) on array of stringsTypeScript:如何在字符串数组上使用带有可能未定义值(可选链接)的 Array.includes
【发布时间】:2022-11-10 16:28:18
【问题描述】:
考虑这个例子:
type SomeType = {
paymentData?: {
paymentMethod?: string;
}
}
const someObj: SomeType = {};
const someTest = ['creditCard', 'payPal'].includes(someObj.paymentData?.paymentMethod);
这在 TypeScript 中不起作用,因为它推断数组元素的类型为 string,因此它要求与 includes 函数一起使用的值也是 string 类型,但 someObj.paymentData?.paymentMethod 可能是未定义的又名类型是string | undefined。我不能使用非空断言运算符 (!),因为它不能在可选链接之后使用。
就 JavaScript 而言,如果 includes 与 undefined 进行检查,那很好,只是 TypeScript 对此不满意。什么是满足 TypeScript 的好方法?
【问题讨论】:
标签:
javascript
typescript
【解决方案1】:
一种方法是将数组转换为string | undefined 的数组。这可能是我的首选方式,因为它不会在转译的 JavaScript 代码中留下任何痕迹。此外,它仍然可以防止您意外检查例如number 实际上没有意义。
const someTest = (['creditCard', 'payPal'] as (string | undefined)[]).includes(someObj.paymentData?.paymentMethod);
在 TypeScript 代码中它有点冗长,所以还有两个选项:
如果定义了someObj.paymentData?.paymentMethod,请预先检查:
const someTest = !!someObj.paymentData?.paymentMethod && ['creditCard', 'payPal'].includes(someObj.paymentData.paymentMethod);
在 undefined 的情况下使用 nullish 合并运算符 (??),通过回退到空字符串来确保值始终是字符串:
const someTest = ['creditCard', 'payPal'].includes(someObj.paymentData?.paymentMethod ?? '');
为了进一步参考,这里是 GitHub 上的一个相关线程,与 Array.includes 函数的类型有关:https://github.com/microsoft/TypeScript/issues/26255
【解决方案3】:
理想情况下,将定义 paymentMethod 类型。通常这是由 API 定义的,如果没有,您应该定义它:
type PaymentMethod = 'creditCard' | 'payPal';
interface SomeType {
paymentMethod?: PaymentMethod;
}
const someObj: SomeType = {};
const someTest = ['creditCard', 'payPal'].includes(someObj.paymentMethod);