Análisis estático

El análisis estático es un tipo de prueba que proporciona una comprobación automatizada de tu código sin ejecutarlo ni escribir una prueba automatizada. que probablemente ya hayas visto este tipo de pruebas si usas un IDE como VSCode, el tipo La verificación que realiza TypeScript es un tipo de análisis estático y puede mostrar como líneas onduladas debajo de errores o advertencias.

ESLint

ESLint es una herramienta que puede brindar feedback sobre posibles problemas en tu base de código. Estos problemas pueden ser de tipo seguro, pero se producen errores o comportamientos no estándares. por derecho propio. ESLint te permite aplicar una serie de reglas que están marcadas en para tu base de código, incluidas muchas de ellas en la versión automático.

Un buen ejemplo de una regla de ESLint es su no-unsafe-finally . Esto evita que escribas sentencias que modifiquen la configuración de control dentro de un bloque finally. Esta es una gran regla, porque hacerlo es una forma inusual de escribir JavaScript que puede ser difícil de seguir. Sin embargo, es que un proceso de revisión de código en buen estado debería detectar.

  try {
    const result = await complexFetchFromNetwork();
    if (!result.ok) {
      throw new Error("failed to fetch");
    }
  } finally {
    // warning - this will 'overrule' the previous exception!
    return false;
  }

ESLint no reemplaza un proceso de revisión saludable (y un que defina cómo debería verse tu base de código), ya que no para capturar todos los enfoques poco ortodoxos que un desarrollador podría intentar implementar en tu base de código. La guía de prácticas de ingeniería de Google tiene una sección breve sobre temas sencillos.

ESLint te permite romper una regla y anotar el código como "permitido". Por ejemplo, Puedes permitir la lógica anterior anotándola de la siguiente manera:

  finally {
    // eslint-disable-next-line no-unsafe-finally
    return false;
  }

Si estás infringiendo una regla constantemente, considera desactivarla. Estos las herramientas te animan a escribir código de cierta manera, pero tu equipo podría a escribir código de una manera diferente y ya somos conscientes de los riesgos de que enfoque.

Por último, habilitar las herramientas de análisis estático en una gran base de código podría crear muchos de ruido inútil (y trabajo pesado para refactorizar) por código que, de lo contrario, funcionaría bien. Para que sea más fácil de habilitar al principio del ciclo de vida de un proyecto.

Complementos ESLint para la compatibilidad con navegadores

Puedes agregar un complemento a ESLint que marque el uso de APIs que no son ampliamente compatibles o no compatibles con tu lista de navegadores de destino. El eslint-plugin-compat puede advertirte cuando una API no esté disponible para tus usuarios, por lo que para que no tengas que hacer un seguimiento continuo de ti mismo.

Verificación de tipos para el análisis estático

Cuando aprenden JavaScript, se suele presentar la idea a los desarrolladores nuevos que es un idioma con escritura deficiente. Es decir, se puede declarar un variable como un tipo, usar la misma ubicación para algo completamente es diferente. Esto es similar a Python y otros lenguajes de programación, pero, lenguajes compilados como C/C++ y Rust.

Este tipo de lenguaje podría ser útil para comenzar, y podría decirse que es la simplicidad que hizo que JavaScript sea tan popular, pero suele ser un punto de falla para algunas bases de código, o, al menos, algo que permita que se produzcan suceder. Por ejemplo, puedes pasar una number en la que un string o un tipo de objeto se esperaba, ese valor escrito incorrectamente puede propagarse a través de varios bibliotecas antes de causar finalmente un objeto TypeError confuso.

TypeScript

TypeScript es la solución más común para la falta de escritura de JavaScript. información. En este curso, se usa ampliamente. Aunque este no es un curso TypeScript, puede ser una parte importante de tu caja de herramientas porque proporciona el análisis estático.

A modo de ejemplo rápido, este código, que espera recibir una devolución de llamada que acepte un string nombre y number edad:

const callback = (name: string, age: string): void => {
  console.info(name, 'is now', age, 'years old!');
};
onBirthday(callback);

Genera el siguiente error cuando se ejecuta a través de TypeScript o incluso cuando se coloca el cursor sobre él. en un IDE:

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
El código del
  ejemplo anterior, se muestra en un IDE con el mensaje de error en una
  de una ventana emergente.
VSCode indica que pasaste un código incorrecto .

En última instancia, el objetivo de usar TypeScript es evitar este tipo de errores: la edad debe ser un number, no un string, es decir, que se arrastra en tu proyecto. Esta puede ser difícil de detectar con otros tipos de prueba. Además, el sistema de tipos puede proporcionar comentarios incluso antes de escribir una prueba. Esto puede facilitar el proceso de escritura de código, ya que recibirás comentarios anticipados sobre los errores de tipo cuando desarrollas software, en lugar de cuando el código finalmente se ejecuta.

La parte más desafiante de usar TypeScript es configurarlo correctamente. Cada El proyecto necesita un archivo tsconfig.json, que, si bien es utilizado principalmente por tsc de línea de comandos en sí misma, también la leen los IDE, como VSCode, junto con muchos otros herramientas de compilación, incluido Vitest. Este archivo contiene cientos de y marcas. Además, puedes encontrar algunos recursos útiles para configurarlo aquí:

Sugerencias generales de TypeScript

Cuando configures y uses TypeScript con un archivo tsconfig.json, conserva lo siguiente:

  • Asegúrate de que los archivos fuente estén incluidos y verificados. Si un archivo misteriosamente, “no tiene errores”, probablemente porque no se está verificando.
  • Describir de forma explícita tipos e interfaces dentro de los archivos .d.ts, en lugar de describirlas implícitamente a medida que escribes funciones, puede hacer que tus base de código más fácil de probar. Es más fácil escribir simulaciones y “falsas” versiones de código cuando las interfaces involucradas son claras. .

TypeScript implícito cualquiera

Una de las opciones de configuración más potentes y gratificantes de TypeScript es el noImplicitAny. Sin embargo, suele ser el más difícil de habilitar sobre todo si ya tienes una base de código grande. (La marca noImplicitAny es habilitado de forma predeterminada si estás en el modo strict, pero no de otra manera).

Esta marca hará que esta función muestre un error:

export function fibonacci(n) {
  if (n <= 1) {
    return 0;
  } else if (n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

Aunque, como lector, está bastante claro que n debe ser un número, TypeScript no puede confirmar esto con seguridad. Si usas VSCode, coloca el cursor sobre la función lo describirá de la siguiente manera:

function fibonacci(n: any): any

Los llamadores de esta función podrán pasar un valor de tipo any (un tipo que permite cualquier otro tipo), no solo un number. Al habilitar la noImplicitAny, puedes proteger este tipo de código durante el desarrollo. sin necesidad de escribir pruebas exhaustivas de lógica empresarial para pasar el código tipos de datos incorrectos en lugares específicos.

La solución simple es marcar tanto el argumento n como el tipo de datos que se muestra de fibonacci como number.

La marca noImplicitAny no te impide escribir explícitamente any en tu base de código. Aún puedes escribir una función que acepte o muestre el tipo any. Solo garantiza que asignes un tipo a cada variable.