ūü•á Type Manipulation, IAT, Indexed Access Types (tipos basados en √≠ndices)

Podemos utilizar indexed access types (tipos basados en índices) para buscar una propiedad específica en otro tipo.

type Persona = { edad: number, nombre: string, vivo: boolean }

type Edad = Persona["edad"];

const edad1 : Edad = 5;
const edad2 : Edad = "quince"; // <- esta línea generará un error

Los IAT son en si mismos tipos, por lo que podemos utilizar unions, keyof u otros tipos.

type Persona = { edad: number; nombre: string; vivo: boolean };

type I1 = Persona["edad" | "nombre"]; // <- union dentro de una referencia a índices

type I2 = keyof Persona;

let miI2 : I2 // <- puede ser number | string o boolean

Otro ejemplo de IAT es el poder utilizar number de forma arbitraria para obtener el tipo de los elementos de un arreglo. Esta posibilidad se puede combinar con typeof para convenientemente capturar el tipo de elemento.

const miArreglo = [
  { nombre: "Martha", edad: 22 },
  { nombre: "Zhenya", edad: 31 },
  { nombre: "Luis", edad: 28 },
];

type Persona = typeof miArreglo[number]; // <- combinaciones posibles { nombre: string, edad: number }

type OtraPersona = typeof miArreglo[number]["nombre"]; // <- string

Si el arreglo no es homogéneo, es decir que las propiedades son diferentes para cada uno de los elementos que lo componen, el resultado de typeof miArreglo[number] es la unión de todos las opciones posibles.

const miArreglo2 = [
  { nombre: "Ana", sexo: "F" },
  { nombre: "Luisa", viva: true },
  { nombre: "Daria", edad: 40 },
];

type Persona2 = typeof miArreglo2[number];
// <- combinaciones { nombre: string, sexo: string } | { nombre: string, viva: boolean } | { nombre: string, edad: number }

Solo se pueden utilizar types cuando se hace indexing, esto quiere decir que no se puede usar const para hacer una referencia a una variable.

const key = "edad"
type Edad = Persona[key]; // <- esto generar√° un error

Sin embargo, se puede utilizar un alias type.

type key = "edad";
type Edad = Persona[key];