"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > TypeScript estrictamente tipado: tipos estáticos completos parciales

TypeScript estrictamente tipado: tipos estáticos completos parciales

Publicado el 2024-08-06
Navegar:192

TypeScript strictly typed - Part full static types

En la parte anterior de esta serie de publicaciones, hablamos sobre la nulidad segura.

Ahora explicaremos y solucionaremos el tercer y último problema del comportamiento predeterminado de TypeScript: restos de escritura dinámica.

Cubriremos:

  • Restos de escritura dinámica
  • Comprobaciones de igualdad real
  • Sin conversiones implícitas en condiciones
  • Notación abreviada de condiciones
  • No se mezclan cadenas ni números

Restos de escritura dinámica

Se supone que TypeScript es un "verificador de tipos estático", a diferencia de JavaScript en el que la escritura es profundamente dinámica.

Pero en una parte anterior de esta serie de publicaciones, también explicamos que TypeScript está construido como un superconjunto de JavaScript.

Entonces el problema es: algunas partes del sistema de escritura dinámica JavaScript permanecen en TypeScript. Por lo tanto, vamos a explicar cómo suprimir estos comportamientos restantes para lograr una escritura estática completa.

Controles de igualdad reales

  • ESLint: eqeqeq
  • Bioma: sospechoso.noDoubleEquals (en recomendado)

El mejor ejemplo del problema son los controles de igualdad. En JavaScript, == no es exactamente una verificación de igualdad, sino una verificación de equivalencia:

1 == "1"; // true

A pesar de que los tipos son diferentes, algunas reglas de conversión entran en acción para que JavaScript pueda comparar los valores. Puede generar muchos errores, porque los detalles de las reglas son difíciles de recordar, a veces son bastante extraños y no son exactamente iguales en todos los lenguajes dinámicos (como PHP, por ejemplo).

Estas comprobaciones de equivalencia solo tienen sentido en un lenguaje escrito dinámicamente como JavaScript. Desde el momento en que decidimos trabajar en TypeScript, solo se deben utilizar comprobaciones de igualdad reales (tipo y valor).

1 === "1"; // false

La regla de pelusa eqeqeq lo aplica.

Las personas que provienen de lenguajes como Java, C# o Rust deben tener especial cuidado con este problema, ya que == en JavaScript o TypeScript no significa lo mismo que en estos lenguajes. En JavaScript y TypeScript, se requiere un tercer = para lograr el mismo comportamiento.

Sin conversiones implícitas en condiciones.

  • ESLint: @typescript-eslint/expresiones-booleanas-estrictas
  • Bioma: regla faltante

¿Crees que las condiciones ahora son seguras? Lamentablemente no, porque las conversiones pueden ser implícitas:

let tax: number | undefined = 0;

if (tax) {
  console.log("Process payment");
}
if (!tax) {
  throw new Error();
}

El ejemplo anterior es equivalente a:

let tax: number | undefined = 0;

if (tax == true) {
  console.log("Process payment");
}
if (tax == false) {
  throw new Error();
}

Como puede ver, había == implícitos, por lo que las conversiones aún ocurren: 0 no es equivalente a verdadero, es equivalente a falso. Por lo tanto, se producirá un error a pesar de que el impuesto sea un valor válido.

La regla de pelusa de expresiones booleanas estrictas no permite tales condiciones implícitas y exige controles reales:

let tax: number | undefined = 0;

if (tax !== undefined) {
  console.log("Process payment");
}
if (tax === undefined) {
  throw new Error();
}

Puede que sea una de las reglas más tediosas a seguir para las personas acostumbradas a las condiciones rápidas en JavaScript, pero para ponerlo en perspectiva, es simplemente la forma normal de hacer las cosas en otros lenguajes como Java, C# o Rust.

Como se muestra en la parte de configuración, deshabilitar las subopciones enableNumber y enableString es importante para evitar todos los errores.

La única excepción permitida es para objetos y matrices: estos casos son seguros porque, a diferencia de las cadenas y los números, no tienen valores falsos. Entonces lo siguiente todavía está bien:

let movie: Movie | undefined;
if (movie) {}
if (!movie) {}

Nota: las declaraciones de cambio ya son seguras ya que usan === internamente.

Notación abreviada de condiciones

  • ESLint: @typescript-eslint/prefer-nullish-coalescing (en tipo estilístico comprobado)
  • Bioma: regla faltante

La regla de pelusa de expresiones booleanas estrictas se encarga de que las comprobaciones de condiciones sean seguras para los tipos, pero existen otras sintaxis de condiciones además de if:

const movieRating = userRating || 5;

// Which is a shorter version of:
const movieRating = userRating == true ? userRating : 5;

Si el usuario calificó 0, 0 equivale a falso, por lo que la calificación será 5 en lugar de 0.

Se puede evitar con JavaScript moderno:

const movieRating = userRating ?? 5;

// Which is a shorter version of:
const movieRating = userRating !== undefined && userRating !== null
  ? userRating
  : 5;

Se puede aplicar mediante la regla de pelusa preferente-nula-coalescente.

Tenga en cuenta que ?? no debe usarse en todas partes: || sigue siendo relevante cuando se trabaja con booleanos.

No se mezclan cadenas ni números

  • ESLint:
    • plantilla preferida
    • @typescript-eslint/restrict-plus-operands (en tipo recomendado verificado)
    • @typescript-eslint/restrict-template-expressions (en tipo recomendado verificado)
  • Bioma:
    • style.useTemplate (en recomendado)
    • faltan otras reglas

En JavaScript, el operador se puede utilizar tanto para la suma matemática de números como para la concatenación de cadenas. Conduce a error.

"There is "   3   1   "Matrix movies"; // 31
"There is "   (3   1)   "Matrix movies"; // 4

El operador debe reservarse para la suma matemática. O al menos, debería usarse solo con datos del mismo tipo, lo que aplica la regla de pelusa de restricción más operandos.

Las cadenas de plantilla de JavaScript moderno deben usarse para la concatenación de cadenas, lo que aplica la regla de pelusa de plantilla preferida:

const movie = `Everything everywhere all at once`;
`${movie} is the best movie!`;

Por el contrario, solo se deben usar cadenas en las cadenas de plantilla, lo que aplica la regla de lint restringir-template-expressions.

Si lo que realmente se desea es mezclar tipos, las conversiones deben ser explícitas:

const total = 3;
`There is ${total.toFixed()} Matrix movies`;

Tenga en cuenta que las cadenas de plantilla se pueden anidar:

const total = 3;
`There is ${total.toFixed()} Matrix movie${total > 1 ? "s" : ""}`;

Conclusión

Este es el final de esta serie de publicaciones. Puedes seguir mi cuenta (botón en la parte superior derecha de esta página) para saber cuándo se publican otras publicaciones sobre TypeScript u otros temas como Angular.

¿Quieres contactarme? Las instrucciones están disponibles en el resumen.

Declaración de liberación Este artículo se reproduce en: https://dev.to/cyrilletuzi/typescript-strictly-typed-part-4-full-static-types-8bc?1 Si hay alguna infracción, comuníquese con [email protected] para eliminar él
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3