Estoy tratando de usar el encadenamiento opcional con una matriz en lugar de un objeto, pero no estoy seguro de cómo hacerlo:
Esto es lo que intento hacer myArray.filter(x => x.testKey === myTestKey)?[0] . También intento algo similar con una función:
let x = {a: () => {}, b: null} console.log(x?b());Pero está dando un error como ese, así que cómo usarlo con una matriz o una función.
Tienes que poner un . después de la ? para usar el encadenamiento opcional:
myArray.filter(x => x.testKey === myTestKey)?.[0] Usando solo el ? solo hace que el compilador piense que está tratando de usar el operador condicional (y luego arroja un error ya que no ve un : más tarde)
El encadenamiento opcional no es solo una cosa de TypeScript, también es una propuesta terminada en JavaScript simple .
Se puede usar con notación de corchetes como la anterior, pero también se puede usar con acceso a propiedades de notación de puntos:
const obj = { prop2: { nested2: 'val2' } }; console.log( obj.prop1?.nested1, obj.prop2?.nested2 );Y con llamadas a funciones:
const obj = { fn2: () => console.log('fn2 running') }; obj.fn1?.(); obj.fn2?.();Acabo de encontrarlo después de buscar un poco en la página de novedades en la documentación oficial .
La forma correcta de hacerlo con una matriz es agregar . despues ?
entonces será como
myArray.filter(x => x.testKey === myTestKey)?.[0]Me gustaría arrojar algo más de luz sobre lo que sucede exactamente con mi caso de pregunta anterior.
myArray.filter(x => x.testKey === myTestKey)?[0]Transpila a
const result = myArray.filter(x => x.testKey === myTestKey) ? [0] : ;Debido a lo cual arroja el error ya que falta algo después: y probablemente no desee que su código se transfiera a esto.
Gracias a la respuesta de Certain Performance, aprendí cosas nuevas sobre TypeScript, especialmente la herramienta https://www.typescriptlang.org/play/index.html .
Bueno, aunque descubrimos la sintaxis correcta, el código no tiene mucho sentido para mí.
El encadenamiento opcional en el código anterior se asegura de que el resultado de myArray.filter(x => x.testKey === myTestKey) no sea null ni undefined (puede echar un vistazo a la salida de TS). Pero de todos modos no es posible, porque el resultado del método de filter siempre es una array . Dado que JavaScript no arroja "Límites de matriz excedidos", siempre está seguro cuando intenta acceder a cualquier índice; no estará undefined si este elemento no existe.
Más ejemplo para que quede claro:
const myArray: string[] = undefined console.log(myArray.filter(x => x)?.[0]) //throws Cannot read property 'filter' of undefined //in this example the optional chaining protects us from undefined array const myArray: string[] = undefined console.log(myArray?.filter(x => x)[0]) //outputs "undefined"ECMA 262 (2020), que estoy probando en Edge Chromium 84, puede ejecutar el operador de encadenamiento opcional sin transpiler de TypeScript:
// All result are undefined const a = {}; console.log(a?.b); console.log(a?.["b-foo-1"]); console.log(a?.b?.()); // Note that the following statements throw exceptions: a?.(); // TypeError: a is not a function a?.b(); // TypeError: a?.b is not a functionNo es necesario que la función esté dentro del objeto, puede ejecutar una función usando un encadenamiento opcional también así:
someFunction?.(); Si existe someFunction , se ejecutará; de lo contrario, omitirá la ejecución y no generará errores.
Esta técnica en realidad es muy útil, especialmente si trabaja con componentes reutilizables y es posible que algunos componentes no tengan esta función.