En JavaScript, comúnmente se considera una buena práctica usar ===
en lugar de ==
por razones obvias y bien conocidas.
En TypeScript, ¿cuál es el preferido? ¿Hay incluso uno que es preferible al otro?
en mi humilde opinión, usando ===
en TypeScript no tiene sentido, ya que la comparación ya solo funciona en tipos iguales, por lo tanto, no tendrá el juego de coerción (más o menos divertido) como en JavaScript simple. Si deja de lado la compatibilidad con JavaScript por un minuto, TypeScript podría incluso deshacerse de ===
no podría?
lhk
version corta:
==
puede hacer conversiones de tipo inesperadas, en Javascript 1=="1"
es true
. Él ===
el operador evita esto. Comparando diferentes tipos con ===
es siempre false
.
El compilador 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 Javascript válido genera un mensaje de error en el compilador de TypeScript. La idea de que todo JavaScript válido también es Typescript válido es un error común. Esto simplemente no es cierto.
versión más larga: Creo que la respuesta aceptada es engañosa. Typescript realmente arregla ==
contra ===
(al menos en la medida de lo posible).
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:
- comparar 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, Typescript está diseñado como un superconjunto de Javascript. Entonces no cambia el comportamiento de estos operadores de comparación. Si tú escribes ==
en Typescript, obtienes conversiones de tipo.
Entonces, ¿cómo se arregla esto? Con el compilador. Si realmente escribe código que compara 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 Typescript válido. Esto no es cierto y el código anterior es un ejemplo en el que el compilador de mecanografiado se quejará de 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: las 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 equals()
método.
Además, es posible que haya notado que el error del compilador es incorrecto. La comparación no siempre se evaluará como falsa. Creo que esto es un error en mecanografiado y tengo presentó un problema.
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 le gustaría.
Compatibilidad con JavaScript (objetivo de diseño de TypeScript 7)
JavaScript debe ser Typescript válido sin cambios.
CoffeeScript no garantiza esto, por lo que puede convertir todas las instancias de ==
a ===
y simplemente decirle a los usuarios no confíes en ==
comportamiento de. TypeScript no puede redefinir ==
sin romper todo el código JavaScript que depende de 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, comprobar los tipos de ambos operandos en tiempo de compilación y rechazar programas comparando variables de distinto tipo.
Además, la compatibilidad no se limita simplemente a los programas de JavaScript; romper la compatibilidad también afecta a los programadores de JavaScript al romper sus suposiciones sobre las diferencias entre ==
y ===
. Ver TypeScript sin objetivo número 7:
Introduzca un comportamiento que probablemente sorprenda a los usuarios. En su lugar, tenga en cuenta 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 ser representable en JavaScript. Además, debe ser JavaScript idiomático cuando sea posible.
Realmente, sin embargo, el compilador de TypeScript podría usar métodos que devuelven valores booleanos para todas las comparaciones, eliminando ==
y ===
enteramente. Esto podría ser incluso más seguro para los usuarios: defina un método de igualdad de tipo seguro en cada tipo de TypeScript (algo así como C++ operator==
simplemente sin sobrecargar).
Entonces hay una solución (para usuarios que comparan clases). unknown
o any
las variables pueden reducir sus tipos antes de usar el método de igualdad con seguridad de tipos.
cual preferir
Utilizar ===
en todas partes que lo haría en JavaScript. Esto tiene la ventaja de evitar los escollos comunes a ==
y no requiere que mantenga un método adicional. La salida del compilador de TypeScript estará cerca de JavaScript idiomático. Usando ==
tiene las mismas trampas que JavaScript, particularmente cuando tienes any
, []
o {}
involucrado. Como excepción, utilizando == null
para comprobar null
o undefined
puede ahorrar dolores de cabeza si el código de la biblioteca es inconsistente.
Un método para la igualdad de referencia (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 tipo.
-
“JavaScript debe ser Typescript válido sin cambios”. No exactamente. Defina “válido”. Aunque emitirá el mismo código, se le permite generar errores si habilita la verificación estricta. El objetivo del diseño solo establece que el tiempo de ejecución no cambia. Nada está garantizado sobre el tiempo de construcción.
– vanuano
28 de septiembre de 2020 a las 14:11
-
¿Podría demostrar un ejemplo del uso incorrecto de “==” permitido por TypeScript?
– vanuano
28 de septiembre de 2020 a las 14:15
-
“Use === en todas partes en JavaScript”: eso solo funciona si ingresa a TypeScript por haber hecho Javascript antes. Los programadores de Java o C# que están entrando en esto podrían optar por mecanografiado sobre Javascript de inmediato, ya que tiene más rigidez de tipo familiar a la que están acostumbrados.
– Nyerguds
7 de enero de 2022 a las 10:41
ivan kleshnin
Tu intuición era correcta. No tiene sentido usar ===
en TypeScript para imitar una comprobación de igualdad. El argumento de que TS compila a JS “debe usar lo que es mejor en JS” no es válido. ¿Por qué? Porque Typescript asegura que ambos operandos de los operadores de comparación tengan el mismo tipo. Cuando ambos operandos tienen el mismo tipo ==
y ===
comportarse de forma idéntica. Y por “idénticamente” me refiero a 100% idénticos, no solo “parecidos”. entonces no hay más correcto o menos correcto versión cuando ambos se comportan exactamente de la misma manera en JavaScript.
Supongo que otros comentaristas aquí solo están buscando formas de preservar su hábito de usar ===
o en otras palabras, racionalizar. Desafortunadamente, la lógica pura dice lo contrario: no tiene sentido reemplazar ==
con ===
a menos que vaya a modificar manualmente el código JS generado, lo que probablemente nunca sea el caso.
yo suelo ===
exclusivamente para verificaciones de identidad (cuando compara x con x, las mismas variables, a veces es necesario en el código de la biblioteca relacionado con la memorización). Y mi contador de errores relacionados con el operador eqeq muestra 0.
Ejemplo:
const s : string = "s"
const n : number = 1
console.log(s == n)
TS2367: This condition will always return 'false' since the types 'string'
and 'number' have no overlap
Dado que Typescript está compilado javascript, creo que el
===
tiene sentido.– Vasileio Pallas
20 de julio de 2019 a las 14:38
Si elimina la compatibilidad con JavaScript, se podrían mejorar muchas cosas, pero creo que los diseñadores de TypeScript valoran mantenerlo lo más cerca posible de JavaScript, sin dejar de agregar escritura.
– kshetline
20 de julio de 2019 a las 14:40
creo que no gira
==
a===
porque Typescript también tiene un tipoany
.– Vasileio Pallas
20 de julio de 2019 a las 14:41
Esto se siente como una pregunta subjetiva / de opinión, por lo que no sé si posiblemente pueda tener una respuesta autorizada. Mis opiniones: • TypeScript está destinado a respaldar las buenas prácticas de JS, ya que el código JS válido es un código TS válido (con posibles advertencias) y, por lo tanto, siempre se emite tal cual (a menos que se dirija a una versión anterior de JS), por lo que prácticamente desea mantener
===
que es JS válido y se considera la mejor práctica. • Si tiene dos expresiones de tipostring | number
puedes compararlos en TypeScript con==
y puede que todavía te sorprendas cuando"3"==3
es verdad.– jcalz
20 de julio de 2019 a las 14:44
@jcalz, la propuesta hipotética aquí era deshacerse de
===
haciendo TypeScript’s==
significa lo mismo como JavaScript===
así que eso==
transpilaría a===
. No era una propuesta confiar en la verificación de tipos mientras se usaba el mismo significado antiguo de==
.– kshetline
20 de julio de 2019 a las 14:54