Arrays en TypeScript

Ahora que ya conocemos los tipos primitivos, damos el siguiente paso natural: los arrays. Y aquí TypeScript empieza a ponerse interesante, porque la sintaxis cambia un poco y aparecen conceptos como tuplas, genéricos e incluso el temido any.

Dos sintaxis para definir arrays

En TypeScript tenemos dos formas equivalentes de tipar un array.

1. Sintaxis clásica con corchetes

Es la más común y concisa:

const numeros: number[] = [1, 2, 3]
const nombres: string[] = ['Ada', 'Grace', 'Linus']

Aquí primero indicamos el tipo y luego añadimos [] para decir que es un array de ese tipo.

Esta suele ser la más utilizada cuando trabajamos con tipos simples como números o strings.

2. Sintaxis con genéricos

También podemos usar:

const numeros: Array<number> = [1, 2, 3]
const nombres: Array<string> = ['Ada', 'Grace', 'Linus']

Esta forma utiliza genéricos, que veremos en profundidad más adelante. Funciona exactamente igual, pero visualmente es diferente.

¿Cuál usar?

  • Para arrays sencillos de tipos primitivos, suele ser más habitual Tipo[].
  • Cuando trabajamos con tipos más complejos o creados por nosotros, muchas veces resulta más cómoda la sintaxis Array<T>.

Ambas son válidas. Elige la que haga tu código más claro.

Importante: las constantes son mutables

Aunque declares un array con const, su contenido puede cambiar.

const notas: number[] = [10, 8, 9]
notas.push(7) // OK, el contenido es mutable

Eso significa que TypeScript no infiere valores concretos, sino que entiende que es un array de números, no “exactamente estos números”, porque más adelante podrías modificarlos.

Si intentas introducir un valor que no corresponde con el tipo definido, entonces sí aparecerá el error:

notas.push('diez') // Error: 'string' no es asignable a 'number'

Tuplas: longitud y tipos fijos por posición

Si necesitas algo más estricto que un array normal, puedes usar tuplas.

Una tupla es un array donde:

  • La longitud está definida
  • El tipo depende de la posición
const coordenada: [number, number] = [40.41, -3.70]
const usuario: [string, number, boolean] = ['Ada', 36, true]

Esto es útil cuando la estructura es fija y el orden importa.

Cuidado con la inferencia y los arrays vacíos

La inferencia de tipos también funciona con arrays. Pero hay un caso peligroso:

const empty = []

Aquí TypeScript no tiene información suficiente para saber qué tipo tendrá el array, así que puede inferir any[].

Y any es algo que quieres evitar siempre.

¿Qué es any?

any aparece cuando TypeScript no puede determinar el tipo. En ese momento:

  • Acepta cualquier valor
  • Permite cualquier operación
  • Básicamente desactiva el control de tipos

Es una mala práctica desactivar errores relacionados con any. Lo correcto es darle pistas al compilador.

Solución

Si sabes que el array será, por ejemplo, de strings, decláralo así desde el principio, aunque esté vacío:

const nombres: string[] = []

De esta forma evitas que TypeScript infiera any[].

Arrays con tipos mixtos

También puedes definir arrays que acepten varios tipos:

const datos: (string | number)[] = ['Ada', 36, 'Grace', 28]
// o con genéricos:
const datos2: Array<string | number> = ['Ada', 36]

Esto puede ser útil en casos reales, como:

  • IDs que pueden venir como string o number
  • Arrays que contienen undefined y luego filtras los valores válidos

Aunque es posible, normalmente conviene mantener los arrays lo más estrictos posible para evitar problemas en el futuro.

Lo que hemos visto

  • Las dos sintaxis para arrays: Tipo[] y Array<T>
  • Cómo funciona la inferencia en arrays
  • Qué son las tuplas y cuándo usarlas
  • Por qué debes evitar any
  • Cómo trabajar con tipos mixtos

En la siguiente clase seguiremos profundizando en el sistema de tipos y empezaremos a ver estructuras más avanzadas.