Inicio / Artículos

Esenciales de TypeScript: Una guía práctica para desarrolladores de JavaScript

TypeScript para desarrolladores de JavaScript, práctico: tipos básicos, tsconfig, modo estricto y un camino de migración paso a paso que hace que el código sea más seguro para modificarlo posteriormente.

Editor: REACTAPP.TOP18 min de lectura4117 palabras

Fuentes: TypeScript for JavaScript Developers: A Practical Beginner’s Guide

Si ya conoces JavaScript, aprender TypeScript se siente menos como aprender un lenguaje completamente nuevo y más como ampliar uno que ya entiendes.

TypeScript es, en esencia, JavaScript mejorado con un sistema de tipos añadido encima.

Sigues trabajando con variables, funciones, arrays, objetos, clases, promesas, async/await, módulos y prácticamente todo lo demás con lo que ya estás familiarizado. Lo que aporta TypeScript es un conjunto de herramientas que detectan errores temprano, antes incluso de que tu código se ejecute en un navegador o en un servidor.

Esta guía explica los conceptos de TypeScript más relevantes para los desarrolladores que ya escriben en JavaScript.

¿Qué es TypeScript?

TypeScript es un lenguaje que se superpone a JavaScript.

En la mayoría de los casos, cualquier programa en JavaScript que escribas también es válido como TypeScript. Lo que aporta TypeScript es la verificación estática de tipos, y al final se compila en JavaScript puro que se ejecuta en navegadores y en Node.js.

Tomemos este sencillo fragmento de JavaScript como ejemplo:

function add(a, b) {
  return a + b;
}

Reescrito en TypeScript, la misma función puede declarar qué tipos de valores acepta:

function add(a: number, b: number): number {
  return a + b;
}

Desglosándolo:

  • a: number exige que a sea un número.
  • b: number exige que b sea un número.
  • El : number al final declara que el valor de retorno de la función es un número.

Con estas anotaciones, TypeScript puede detectar una llamada a función incorrecta antes incluso de que comience la ejecución:

add(10, 20);      // Correct
add("10", "20");  // TypeScript error

En JavaScript puro, llamar a la función con argumentos de cadena devolvería silenciosamente "1020", ya que el operador más uniría las cadenas en lugar de sumar números. TypeScript detecta este tipo de comportamiento no intencionado con antelación.

¿Por qué usar TypeScript?

La flexibilidad de JavaScript es una ventaja, pero también puede abrir la puerta a errores sutiles.

Tomemos esta función como ejemplo:

function calculateDiscount(price, percentage) {
  return price - price * percentage / 100;
}

Llamarla correctamente funciona como se espera:

calculateDiscount(1000, 10);

Pero nada impide llamarla de esta manera en su lugar:

calculateDiscount("1000", "ten");

El problema que surge solo se manifiesta una vez que el código se ejecuta realmente.

Con TypeScript, puedes especificar los tipos que espera la función:

function calculateDiscount(
  price: number,
  percentage: number
): number {
  return price - price * percentage / 100;
}

Ahora TypeScript marca los argumentos inválidos de inmediato, sin necesidad de ejecutar primero el código.

Algunas de las principales ventajas que esto ofrece son:

  • Detección de errores mientras aún se está escribiendo el código
  • Mejor soporte para autocompletado en el editor
  • Refactorización más sencilla y segura
  • Estructuras de funciones y objetos más explícitas
  • Colaboración más fluida en bases de código más grandes
  • Tipos que funcionan como documentación integrada

El valor de TypeScript se vuelve especialmente evidente cuando un proyecto crece más allá de unos pocos archivos o involucra a más de un colaborador.

Instalación de TypeScript

Se puede instalar TypeScript a nivel global con:

npm install -g typescript

Para confirmar la versión instalada, ejecute:

tsc --version

Luego cree un archivo llamado:

app.ts

Agregue algo de código en TypeScript a él:

const message: string = "Hello TypeScript";
console.log(message);

Compile el archivo con:

tsc app.ts

Esto genera un resultado en JavaScript compilado:

app.js

Puede ejecutar el resultado directamente con Node.js:

node app.js

En entornos de producción, herramientas y frameworks como React, Next.js, Angular y NestJS suelen encargarse automáticamente de este paso de compilación.

El archivo tsconfig.json

La mayoría de los proyectos en TypeScript dependen de un archivo tsconfig.json para configurar el compilador.

Puede generar uno con:

tsc --init

Una configuración mínima podría verse así:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

Aquí hay algunos de los parámetros más importantes:

target

Esto controla qué versión de JavaScript genera el compilador.

"target": "ES2020"

module

Esto establece el formato de módulo utilizado en la salida compilada.

"module": "ESNext"

strict

Al activar esta opción, se habilita un nivel más estricto de verificación de tipos.

"strict": true

Para cualquier proyecto nuevo, se recomienda encarecidamente dejar el modo estricto activado.

rootDir

Esto indica al compilador dónde se encuentran los archivos de código fuente en TypeScript.

"rootDir": "./src"

outDir

Esto define dónde se debe escribir el código JavaScript compilado.

"outDir": "./dist"

Tipos básicos

TypeScript incluye varios tipos primitivos que ya conocerá.

Cadena de texto

let username: string = "Vijeet";

Número

let experience: number = 10;

TypeScript no distingue entre números enteros y de punto flotante; ambos se clasifican como number.

let age: number = 35;
let price: number = 999.99;

Booleano

let isActive: boolean = true;

Null y Undefined

let emptyValue: null = null;
let missingValue: undefined = undefined;

Bajo el modo estricto, será necesario manejar null y undefined de manera más deliberada.

Inferencia de tipos

No es necesario anotar cada valor manualmente.

A menudo, TypeScript puede determinar el tipo de una variable basándose en lo que se le asigna.

let city = "Ahmedabad";

Aquí, TypeScript reconoce automáticamente que city es una cadena de texto.

Intentar reasignarlo de esta manera provocará un error:

city = 100;

La misma lógica se aplica aquí:

let total = 500;

TypeScript infiere que total contiene un número.

Depender de la inferencia mantiene su código menos saturado. Reserve las anotaciones de tipo explícitas para aquellos lugares donde aporten claridad real, como los parámetros de funciones, las estructuras de respuesta de API y las estructuras de objetos más complejas.

Arreglos

Aquí hay un arreglo simple de JavaScript:

const skills = ["JavaScript", "React", "Node.js"];

TypeScript permite anotar el tipo de los elementos del array:

const skills: string[] = [
  "JavaScript",
  "React",
  "Node.js"
];

También se puede escribir con la sintaxis genérica:

const skills: Array<string> = [
  "JavaScript",
  "React",
  "Node.js"
];

La misma idea se aplica a los arrays numéricos:

const scores: number[] = [75, 82, 91];

TypeScript impide cualquier intento de insertar un valor del tipo incorrecto:

scores.push(95);       // Correct
scores.push("ninety"); // Error

Objetos

Se puede dar a un objeto simple de JavaScript una estructura explícita.

const user: {
  name: string;
  age: number;
  isAdmin: boolean;
} = {
  name: "Vijeet",
  age: 35,
  isAdmin: true
};

Si una propiedad falta o tiene el tipo incorrecto, TypeScript la marca como un error.

const user: {
  name: string;
  age: number;
} = {
  name: "Vijeet"
};

Aquí, la propiedad age requerida falta en el objeto.

Cuando se necesita reutilizar la misma estructura de objeto en varios lugares, las interfaces o los alias de tipo son más adecuados que escribir la estructura directamente cada vez.

Interfaces

Una interfaz define la estructura que se espera que tenga un objeto.

interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

Una vez definida, puedes reutilizar esa interfaz en cualquier lugar:

const user: User = {
  id: 1,
  name: "Vijeet",
  email: "vijeet@example.com",
  isActive: true
};

Las interfaces son útiles en situaciones como:

  • describir los detalles almacenados de un usuario
  • modelar un elemento de catálogo
  • validar los campos introducidos en un formulario
  • determinar la estructura de los datos devueltos por una llamada a API
  • definir los parámetros pasados a un componente
  • representar una fila de una tabla de base de datos

Por ejemplo:

interface Product {
  id: number;
  title: string;
  price: number;
}

Luego, una función puede aceptar un Product como parámetro:

function displayProduct(product: Product): void {
  console.log(`${product.title}: ₹${product.price}`);
}

Propiedades opcionales

Algunas propiedades de un objeto no siempre estarán presentes.

Puedes marcarlas añadiendo un signo de interrogación después del nombre de la propiedad:

interface User {
  id: number;
  name: string;
  phone?: string;
}

Los dos objetos siguientes cumplen con la interfaz:

const userOne: User = {
  id: 1,
  name: "Amit"
};
const userTwo: User = {
  id: 2,
  name: "Neha",
  phone: "9876543210"
};

Dado que phone es opcional, su tipo se convierte en:

string | undefined

Eso significa que debe verificar si existe antes de usarlo:

if (userTwo.phone) {
  console.log(userTwo.phone);
}

Alias de tipo

Un alias de tipo le permite asignar un nombre reutilizable a cualquier tipo.

type UserId = number;

Luego puede usar ese alias como tipo:

const id: UserId = 101;

Los alias de tipo brillan especialmente al describir uniones o combinaciones de tipos más complejas.

type Status = "pending" | "approved" | "rejected";

Con este alias en su lugar, solo se permiten tres cadenas específicas:

let applicationStatus: Status = "pending";

Intentar usar cualquier otra cosa genera un error:

applicationStatus = "completed";

Interfases vs alias de tipo

Tanto las interfaces como los alias de tipo pueden modelar la estructura de un objeto.

Aquí está la versión con interfaz:

interface Customer {
  name: string;
  email: string;
}

Y la versión equivalente con alias de tipo:

type Customer = {
  name: string;
  email: string;
};

Como regla práctica para los principiantes:

  • Utilice interface al describir objetos o estructuras de clase.
  • Utilice type al trabajar con uniones, alias para primitivos, tuplas o tipos combinados más complejos.

No obstante, esta no es una regla estricta; en muchos casos ambos enfoques funcionan igual de bien.

Tipos de unión

Un tipo de unión permite que un valor adopte uno de varios tipos posibles.

let userId: string | number;

Ambas asignaciones son válidas:

userId = 101;
userId = "USR-101";

Los tipos de unión son útiles cuando los datos provenientes del mundo real no siempre siguen un formato fijo.

function printId(id: string | number): void {
  console.log(id);
}

Antes de llamar a un método que solo existe en uno de los tipos posibles, primero debe restringir el valor:

function printId(id: string | number): void {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id.toFixed(0));
  }
}

Esta técnica se conoce como reducción de tipo.

Tipos literales

Los tipos literales limitan una variable a un conjunto exacto y predefinido de valores.

type Theme = "light" | "dark" | "system";

Esta asignación está bien:

let selectedTheme: Theme = "dark";

Pero esta es rechazada:

selectedTheme = "blue";

Los tipos literales son adecuados para casos como:

  • el estado actual de un registro
  • el nivel de permisos asignado a un usuario
  • una configuración de tema visual
  • el estilo visual de un botón
  • el verbo HTTP utilizado en una solicitud
  • el modo en el que funciona una aplicación

Como ejemplo:

type UserRole = "admin" | "editor" | "customer";

Funciones

Para los parámetros de función, el tipo va justo después del nombre del parámetro.

function greet(name: string): string {
  return `Hello, ${name}`;
}

El tipo de retorno de la función va después del paréntesis de cierre de la lista de parámetros.

function multiply(a: number, b: number): number {
  return a * b;
}

Cuando una función no devuelve un valor, anótela con void.

function logMessage(message: string): void {
  console.log(message);
}

Los parámetros opcionales se marcan con ?:

function greetUser(
  name: string,
  title?: string
): string {
  if (title) {
    return `Hello, ${title} ${name}`;
  }
 return `Hello, ${name}`;
}

Los valores por defecto de los parámetros se comportan exactamente como en JavaScript puro:

function calculateTax(
  amount: number,
  rate: number = 18
): number {
  return amount * rate / 100;
}

Tipado de funciones flecha

Puedes anotar las funciones flecha de la misma manera.

const subtract = (
  a: number,
  b: number
): number => {
  return a - b;
};

He aquí una forma más compacta:

const subtract = (
  a: number,
  b: number
): number => a - b;

El tipo any

Al asignar el tipo any a un valor, se le indica a TypeScript que deje de verificarlo por completo.

let data: any = "Hello";
data = 100;
data = true;
data = { name: "Vijeet" };

Aunque esto pueda parecer conveniente al principio, depender demasiado de any hace que se pierda la mayor parte de las ventajas que ofrece TypeScript.

Toma este ejemplo:

function processData(data: any): any {
  return data.someProperty.someMethod();
}

No hay nada que TypeScript pueda hacer para detectar errores en esta función.

Reserve any para situaciones en las que sea realmente inevitable — por ejemplo, al convertir gradualmente una base de código JavaScript, o al tratar con datos de terceros que carecen de definiciones de tipo adecuadas.

El tipo unknown

unknown le brinda una forma más segura de representar valores cuyo tipo no se conoce de antemano.

let value: unknown;

Igual que any, acepta cualquier tipo de valor:

value = "Hello";
value = 100;
value = true;

Pero a diferencia de any, TypeScript le obliga a restringir el tipo antes de poder usarlo realmente:

if (typeof value === "string") {
  console.log(value.toUpperCase());
}

Eso hace que unknown sea adecuado para:

  • Datos provenientes de APIs externas
  • Valores analizados desde JSON
  • Objetos de error capturados en un bloque try/catch
  • Entrada proporcionada por los usuarios
  • Cualquier cosa cuya estructura aún no se ha determinado

Afirmaciones de tipo

Hay ocasiones en las que se dispone de más información sobre un valor de la que TypeScript puede inferir por sí solo.

Una aserción de tipo permite indicarle al compilador cómo tratar ese valor.

const input = document.getElementById(
  "email"
) as HTMLInputElement;

Una vez realizada la aserción, se pueden acceder a las propiedades específicas de ese tipo:

console.log(input.value);

Tenga en cuenta que una aserción no cambia nada en tiempo de ejecución; solo modifica la forma en que TypeScript interpreta el valor durante la compilación.

Por este motivo, se deben utilizar las aserciones con moderación y solo cuando se tenga certeza sobre la estructura real de los datos.

Tuplas

Una tupla es un array con un número definido de posiciones, donde cada posición tiene su propio tipo especificado.

let userEntry: [number, string];
userEntry = [1, "Vijeet"];

Aquí, la primera posición debe contener un número y la segunda una cadena de texto.

Lo siguiente fallaría:

userEntry = ["Vijeet", 1];

Las tuplas son útiles para datos pequeños de forma fija o valores emparejados:

type Coordinate = [number, number];
const location: Coordinate = [23.0225, 72.5714];

Cuando los datos se vuelven más complejos o se necesitan nombres de campos descriptivos, los objetos simples suelen ser más claros.

Enum

Una enum permite definir un grupo fijo de constantes con nombre.

enum OrderStatus {
  Pending,
  Processing,
  Shipped,
  Delivered
}

Puedes hacer referencia a ellas de esta manera:

let status: OrderStatus = OrderStatus.Processing;

Asignar valores de cadena a las enums suele mejorar la legibilidad:

enum PaymentStatus {
  Pending = "pending",
  Paid = "paid",
  Failed = "failed"
}

No obstante, muchos usuarios de TypeScript prefieren los tipos union en su lugar, especialmente para escenarios más simples:

type PaymentStatus =
  | "pending"
  | "paid"
  | "failed";

Los tipos union suelen generar menos código JavaScript al compilarse y constituyen una opción sólida por defecto para la mayoría del código front-end.

Clases

TypeScript extiende las clases normales de JavaScript con verificación de tipos.

class Employee {
  name: string;
  salary: number;
  constructor(name: string, salary: number) {
    this.name = name;
    this.salary = salary;
  }  getAnnualSalary(): number {
    return this.salary * 12;
  }
}

La instanciación de la clase se parece a la del JavaScript:

const employee = new Employee("Rahul", 50000);
console.log(employee.getAnnualSalary());

Los modificadores de acceso también forman parte de la sintaxis de clases de TypeScript.

class BankAccount {
  public accountHolder: string;
  private balance: number;
  constructor(accountHolder: string, balance: number) {
    this.accountHolder = accountHolder;
    this.balance = balance;
  }  public getBalance(): number {
    return this.balance;
  }
}

Los modificadores principales son:

  • public: visible desde cualquier lugar
  • private: visible solo dentro de la clase misma
  • protected: visible dentro de la clase y en cualquier subclase
  • readonly: puede ser asignado una vez pero no reasignado posteriormente

Genéricos

Los genéricos permiten escribir código flexible y reutilizable que mantiene una seguridad de tipos completa independientemente del tipo de entrada.

Tome esta función como punto de partida:

function returnValue(value: any): any {
  return value;
}

Dado que depende de any, TypeScript no puede indicarle nada sobre el resultado que genera.

Reescribirlo con un parámetro genérico soluciona eso:

function returnValue<T>(value: T): T {
  return value;
}

Ahora el tipo de retorno coincide con lo que se pasó:

const text = returnValue<string>("Hello");
const count = returnValue<number>(100);

En muchos casos, TypeScript puede inferir el tipo genérico automáticamente, por lo que no es necesario escribirlo explícitamente:

const text = returnValue("Hello");
const count = returnValue(100);

Los genéricos aparecen constantemente al trabajar con arrays, estructuras de respuestas de API, componentes UI reutilizables, hooks personalizados y utilidades auxiliares.

function getFirstItem<T>(items: T[]): T | undefined {
  return items[0];
}

Se usan de esta manera:

const firstNumber = getFirstItem([10, 20, 30]);
const firstName = getFirstItem(["Amit", "Neha"]);

Promesas y funciones asíncronas

Las funciones declaradas con async siempre se resuelven en promesas.

async function getUsername(): Promise<string> {
  return "Vijeet";
}

Una función asíncrona que se resuelve en un objeto de usuario podría verse así:

interface User {
  id: number;
  name: string;
}
async function getUser(): Promise<User> {
  return {
    id: 1,
    name: "Vijeet"
  };
}

Y para una lista de usuarios, se envolvería el tipo de retorno en un array:

async function getUsers(): Promise<User[]> {
  return [
    { id: 1, name: "Vijeet" },
    { id: 2, name: "Rahul" }
  ];
}

Asignar los tipos adecuados a los resultados de la API de esta manera protege el resto de su código base de errores posteriores.

Definición de tipos para las respuestas de la API

Imagínese un endpoint que devuelve registros de productos:

interface Product {
  id: number;
  title: string;
  price: number;
}

Puede envolver la llamada a fetch en una función que declare su tipo de retorno:

async function fetchProducts(): Promise<Product[]> {
  const response = await fetch("/api/products");
  if (!response.ok) {
    throw new Error("Unable to fetch products");
  }  const data: Product[] = await response.json();  return data;
}

Hay un detalle importante que recordar: TypeScript no tiene forma de verificar estos datos una vez que la aplicación está en ejecución.

La línea:

const data: Product[] = await response.json();

solo indica al compilador que trate la respuesta analizada como un Product[] — no confirma que el servidor realmente haya enviado objetos con esa estructura.

En aplicaciones donde la corrección es crucial, los desarrolladores suelen combinar TypeScript con una biblioteca de validación en tiempo de ejecución como Zod para subsanar esta deficiencia.

Manejo de elementos DOM

Los tipos de elementos del navegador vienen integrados en TypeScript.

const button = document.querySelector(
  "#submit-button"
);

El compilador sabe que esta consulta podría devolver un resultado vacío, por lo que el tipo de resultado incluye null junto con el tipo de elemento.

Eso significa que debe protegerse contra el caso en que falte el elemento antes de usarlo:

if (button) {
  button.addEventListener("click", () => {
    console.log("Button clicked");
  });
}

Si necesita un tipo de elemento más específico, puede afirmarlo:

const emailInput = document.querySelector(
  "#email"
) as HTMLInputElement | null;

Luego lea su valor una vez que haya confirmado que existe:

if (emailInput) {
  console.log(emailInput.value);
}

TypeScript no reemplaza la validación en tiempo de ejecución

Este punto merece énfasis, especialmente para los desarrolladores que vienen directamente de JavaScript.

Las verificaciones de TypeScript solo ocurren en tiempo de desarrollo y compilación. Una vez que su código se compila a JavaScript, todas las anotaciones de tipo desaparecen.

Tome esta función:

function double(value: number): number {
  return value * 2;
}

Después de la compilación, se convierte aproximadamente en:

function double(value) {
  return value * 2;
}

En ese punto, ya no queda rastro de la información de tipo original que permitiera hacer cumplir alguna regla.

Como resultado, TypeScript no puede garantizar que:

  • Una API haya devuelto realmente datos bien formados
  • Un usuario haya introducido un valor válido
  • Un registro de la base de datos tenga la estructura esperada
  • Un servicio de terceros haya respetado su propio contrato documentado

Cualquier elemento que provenga del exterior de su código aún necesita ser verificado mientras el programa está en ejecución.

Migrar un proyecto JavaScript existente

La conversión de una base de código JavaScript a TypeScript no tiene por qué realizarse en una sola reescritura integral.

Una migración paso a paso suele funcionar mejor en la práctica.

Paso 1: Instalar TypeScript

npm install --save-dev typescript

Paso 2: Crear tsconfig.json

npx tsc --init

Paso 3: Permitir JavaScript temporalmente

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false
  }
}

Paso 4: Renombrar los archivos gradualmente

Cambie un archivo de la siguiente manera:

utils.js

a:

utils.ts

Y para los componentes de React, convierta:

Button.jsx

en:

Button.tsx

Paso 5: Corregir errores uno por archivo

Es útil comenzar con funciones utilitarias, modelos de datos compartidos y componentes más pequeños, reservando la lógica de aplicación más compleja para después.

Este enfoque gradual es una de las mayores ventajas prácticas que ofrece TypeScript al integrarlo en un proyecto existente.

Errores comunes que cometen los desarrolladores de JavaScript

Usar any en todas partes

const user: any = getUser();

Esto podría silenciar una queja inmediata del compilador, pero también elimina toda la verificación de tipos.

Un enfoque mejor es definir una interfaz real:

interface User {
  id: number;
  name: string;
}

Añadir tipos a cada variable

No hay necesidad de escribir esto:

const name: string = "Vijeet";
const count: number = 10;
const active: boolean = true;

porque la inferencia de tipos ya determina estos tipos por sí sola:

const name = "Vijeet";
const count = 10;
const active = true;

Reserve las anotaciones explícitas para los casos en que realmente aporten claridad.

Ignorar null

Este código puede fallar en tiempo de ejecución:

const element = document.querySelector("#app");
element.innerHTML = "Hello";

El elemento que se consulta podría simplemente no existir en la página.

Proteja contra esa posibilidad:

const element = document.querySelector("#app");
if (element) {
  element.innerHTML = "Hello";
}

Usar afirmaciones de tipo para ocultar problemas

Escribir algo así es arriesgado:

const user = apiResponse as User;

La afirmación no verifica nada sobre la respuesta real de la API; simplemente le dice al compilador que confíe en sus palabras.

Tratar a TypeScript como un entorno de ejecución diferente

TypeScript no es ejecutado directamente por el navegador. Primero se compila a JavaScript puro antes de que se ejecute.

Eso significa que todo lo que ya sabes sobre JavaScript sigue siendo aplicable.

Un ejemplo práctico

Considera un carrito de compras simple, escrito de la manera en que normalmente lo construirías en JavaScript, pero ahora con tipos de TypeScript añadidos encima.

interface CartItem {
  id: number;
  name: string;
  price: number;
  quantity: number;
}

function calculateCartTotal(
  items: CartItem[]
): number {
  return items.reduce((total, item) => {
    return total + item.price * item.quantity;
  }, 0);
}
const cart: CartItem[] = [
  {
    id: 1,
    name: "Keyboard",
    price: 2500,
    quantity: 1
  },
  {
    id: 2,
    name: "Mouse",
    price: 1200,
    quantity: 2
  }
];
const total = calculateCartTotal(cart);
console.log(`Cart total: ₹${total}`);

Con esto en su lugar, la función ahora está protegida contra entradas inválidas en el carrito.

Por ejemplo, el siguiente fragmento no se compilará:

const invalidCart: CartItem[] = [
  {
    id: 1,
    name: "Keyboard",
    price: "2500",
    quantity: 1
  }
];

El problema es que price se establece como cadena cuando debería ser un número.

¿Debería usar TypeScript todo proyecto en JavaScript?

No siempre.

JavaScript puro sigue funcionando bien en casos como:

  • Ejercicios pequeños
  • Scripts simples
  • Prototipos rápidos
  • Páginas de aterrizaje básicas
  • Herramientas internas temporales
  • TypeScript suele ser más útil en situaciones como:

    • Aplicaciones frontales de gran tamaño
    • Bases de código de React y Next.js
    • Servicios backend de Node.js
    • Bases de código compartidas entre equipos
    • Productos de larga duración
    • Proyectos que manejan estructuras de datos complejas
    • Aplicaciones desarrolladas y mantenidas por varios desarrolladores

    En general, cuanto más grande y duradero sea un proyecto, mayores serán los beneficios de adoptar TypeScript.

    Consideraciones finales

    TypeScript no es un sustituto de JavaScript: mejora la experiencia al escribir JavaScript al añadir una capa adicional de seguridad a tu código.

    Si vienes del mundo de JavaScript, ya cuentas con la mayor parte de los conocimientos necesarios:

    • Variables
    • Funciones
    • Objetos
    • Arreglos
    • Clases
    • Promesas
    • Módulos
    • Código asíncrono

    Lo que queda por aprender se refiere principalmente a cómo expresar la estructura de tus datos.

    Un buen punto de partida incluye:

    1. Tipos primitivos
    2. Tipos de parámetros y valores devueltos para funciones
    3. Interfases
    4. Tipos de unión
    5. Propiedades opcionales
    6. Genéricos
    7. Respuestas tipadas desde APIs

    No intentes absorber todas las características avanzadas de inmediato. Comienza anotando el JavaScript cotidiano y deja que las necesidades de tus proyectos reales guíen lo que aprendas a continuación.

    Una vez que TypeScript se convierta en algo natural, volver al JavaScript simple y sin tipado puede empezar a parecer inesperadamente precario.

    Lecturas relacionadas