Sofía, parte de nuestro staff, nos ha hecho el favor de crear esta sección porque domina muy bien el tema.
Solución:
Imagina que estás diseñando TypeScript desde cero. Esencialmente, está tratando de optimizar para hacer que el código más seguro sea más fácil de escribir (objetivo de diseño de TypeScript 1) con algunas advertencias que le impiden hacer todo lo que desea.
Compatibilidad con JavaScript (objetivo de diseño 7 de TypeScript)
JavaScript debe ser Typecript válido sin cambios.
CoffeeScript no ofrece garantías al respecto, por lo que puede convertir todas las instancias de ==
para ===
y simplemente dile a los usuarios no confíes en ==
comportamiento. TypeScript no puede redefinir ==
sin romper todo el código JavaScript que se basa en su comportamiento (a pesar de que esto tiene tristes implicaciones para 3).
Esto también implica que TypeScript no puede cambiar la funcionalidad de ===
para, por ejemplo, verificar los tipos de ambos operandos en tiempo de compilación y rechazar programas comparando variables de diferentes tipos.
Además, la compatibilidad no se limita simplemente a los programas JavaScript; romper la compatibilidad también afecta a los programadores de JavaScript al romper sus suposiciones sobre las diferencias entre ==
y ===
. Consulte TypeScript no objetivo número 7:
Introduzca un comportamiento que pueda sorprender a los usuarios. En su lugar, tenga la debida consideración por los patrones adoptados por otros lenguajes de uso común.
JavaScript como destino de la compilación (objetivo de diseño 4 de TypeScript)
Todo TypeScript debe poder representarse en JavaScript. Además, debería ser JavaScript idiomático siempre que sea posible.
Sin embargo, en realidad, el compilador de TypeScript podría usar métodos que devuelvan valores booleanos para todas las comparaciones, eliminando ==
y ===
enteramente. Esto incluso podría ser más seguro para los usuarios: defina un método de igualdad de tipo seguro en cada tipo de TypeScript (como C ++ operator==
, solo sin sobrecargar).
Entonces hay una solución (para usuarios que comparan clases). unknown
o any
las variables pueden tener sus tipos reducidos antes de usar el método de igualdad con seguridad de tipos.
Cual preferir
Usar ===
donde quiera que lo haría en JavaScript. Esto tiene la ventaja de evitar las trampas comunes a ==
y no requiere que mantenga un método adicional. La salida del compilador de TypeScript se acercará al JavaScript idiomático. Utilizando ==
tiene las mismas dificultades que JavaScript, especialmente cuando tienes any
, []
, o involucrado. Como excepción, usando
== null
para comprobar null
o undefined
puede ahorrarle dolores de cabeza si el código de la biblioteca es inconsistente.
Un método para la igualdad de referencias (comportamiento como ===
para clases) podría confundirse con una verificación de igualdad recursiva profunda / valor. Es más, ===
se usa ampliamente en TypeScript, y hacer que su código se ajuste a las convenciones suele ser más importante que cualquier pequeña seguridad de tipos.
version corta:
==
puede hacer conversiones de tipo inesperadas, en Javascript 1=="1"
es true
. los ===
El operador evita esto. Comparando diferentes tipos con ===
es siempre false
.
El compilador de mecanografiado emitirá un mensaje de error cuando compare diferentes tipos con ==
. Esto elimina las conversiones de tipo inesperadas que pueden ocurrir con ==
en Javascript.
Este es un caso en el que un Javascript válido conduce a un mensaje de error en el compilador de mecanografiado. La idea de que todo Javascript válido también es Typecript válido es un error común. Esto simplemente no es true.
versión más larga: Creo que la respuesta aceptada es engañosa. Typecript realmente arregla ==
vs ===
(en la medida de lo posible al menos).
En Javascript hay dos operadores de comparación:
==
: Al comparar valores primitivos, como números y cadenas, este operador aplicará una conversión de tipo antes de realizar la comparación.1 == "1"
evalúa atrue
.===
: Este operador no realiza conversiones de tipos. Si los tipos no coinciden, siempre volverá.false
.
Además, ambos operadores compararán los tipos de referencia en función de sus referencias. Dos objetos separados nunca se consideran iguales entre sí, incluso si almacenan los mismos valores:
let a = val:1;
let b = val:1;
c = a;
a==b; // false
a===b; // false
a==c; //true
a===c; //true
Ahí tienes las dos fuentes comunes de errores en las comparaciones de Javascript:
- comparando diferentes tipos con
==
puede dar lugar a conversiones de tipo inesperadas. - La comparación de objetos y matrices se basa en referencias, no en valores almacenados en su interior.
Como ya dice la respuesta existente, Typecript está diseñado como un superconjunto de Javascript. Por tanto, no cambia el comportamiento de estos operadores de comparación. Si tú escribes ==
en TypeScript, obtienes conversiones de tipos.
Entonces, ¿cómo se soluciona esto? Con el compilador. Si realmente escribe código que compare tipos incompatibles con ==
es un error del compilador. Intente compilar el siguiente ejemplo:
let str = "1";
let num = 1;
console.log(str == num);
El compilador te dirá:
comparisons.ts:4:13 - error TS2367: This condition will always return 'false' since the types 'string' and 'number' have no overlap.
4 console.log(str == num);
~~~~~~~~~~
Found 1 error.
Es un error común pensar que cualquier JavaScript válido también es Typecript válido. Esto no es true y el código anterior es un ejemplo en el que el compilador mecanografiado se quejará de un Javascript válido.
Esto corrige la primera de las dos fuentes de errores: conversiones de tipo inesperadas. No se ocupa de la segunda fuente de errores: comparaciones basadas en referencias. Hasta donde yo sé, cuando desea hacer una comparación basada en los valores almacenados por los objetos, simplemente no puede usar estos operadores. Tendrás que implementar el tuyo propio equals()
método.
Además, es posible que haya notado que el error del compilador es incorrecto. La comparación no siempre evaluará false. Creo que esto es un error en el mecanografiado y he presentado un problema.