Considere este ejemplo:
type SomeType = { paymentData?: { paymentMethod?: string; } } const someObj: SomeType = {}; const someTest = ['creditCard', 'payPal'].includes(someObj.paymentData?.paymentMethod); Esto no funciona en TypeScript porque infiere que el tipo de los elementos de la matriz es una string , por lo que requiere que el valor utilizado con la función includes también sea del tipo string , pero someObj.paymentData?.paymentMethod posiblemente no esté definido, también conocido como el tipo es string | undefined No puedo usar el operador de aserción no nulo ( ! ) ya que no se puede usar después del encadenamiento opcional.
En cuanto a JavaScript, está perfectamente bien si includes controles con undefined , solo que TypeScript no está contento con eso. ¿Cuáles son buenas formas de satisfacer a TypeScript aquí?
Una forma es convertir la matriz en una matriz de string | undefined Esta es probablemente mi forma preferida, ya que no deja ningún rastro en el código JavaScript transpilado. También le impide verificar accidentalmente, por ejemplo, un number que en realidad no tiene sentido.
const someTest = (['creditCard', 'payPal'] as (string | undefined)[]).includes(someObj.paymentData?.paymentMethod);Es un poco detallado en el código TypeScript, por lo que hay dos opciones más:
Comprobando por adelantado si está definido someObj.paymentData?.paymentMethod :
const someTest = !!someObj.paymentData?.paymentMethod && ['creditCard', 'payPal'].includes(someObj.paymentData.paymentMethod); Asegurarse de que el valor sea siempre una cadena recurriendo a una cadena vacía en caso de que no esté undefined usando el operador de fusión nulo ( ?? ):
const someTest = ['creditCard', 'payPal'].includes(someObj.paymentData?.paymentMethod ?? ''); Para mayor referencia, aquí hay un hilo relacionado en GitHub sobre la tipificación de la función Array.includes : https://github.com/microsoft/TypeScript/issues/26255
Puede usar el operador de aserción no nulo - ! :
type SomeType = { paymentMethod?: string; } const someObj: SomeType = {}; const someTest = ['creditCard', 'payPal'].includes(someObj.paymentMethod!);Idealmente, se paymentMethod el tipo de método de pago. Por lo general, esto está definido por una API, si no, debe definirlo:
type PaymentMethod = 'creditCard' | 'payPal'; interface SomeType { paymentMethod?: PaymentMethod; } const someObj: SomeType = {}; const someTest = ['creditCard', 'payPal'].includes(someObj.paymentMethod);