Las interfaces en TypeScript nos permiten definir estructuras de datos con gran precisión, y una de las características más interesantes, aunque menos conocidas al principio, son los accesores indizados. Estos accesores nos permiten especificar cómo se puede acceder a las propiedades de un objeto o a los elementos de un array mediante índices, ya sean numéricos o de tipo string.
En JavaScript, tanto los arrays como los objetos son tipos indizables. Esto significa que podemos acceder a sus elementos o propiedades usando corchetes con un índice o una clave. Por ejemplo, en un array podemos acceder a la posición cero con vector[0], y en un objeto podemos acceder a una propiedad con object["displayName"]. Aunque normalmente usamos la notación de punto para acceder a propiedades de objetos, la notación con corchetes también es válida y reconocida por TypeScript, que infiere correctamente el tipo del valor accedido.
Lo que podemos hacer en TypeScript es definir interfaces que indiquen que un objeto debe soportar este tipo de acceso indizado. Para ello, dentro de la interfaz declaramos un accesor indizado, que tiene una sintaxis particular: usamos corchetes con un parámetro que representa el índice, y especificamos el tipo que debe devolver ese acceso. Por ejemplo, si queremos que un objeto permita acceder a sus elementos mediante un índice numérico y que el valor devuelto sea un booleano, definimos la interfaz así:
interface IndieFable {
[index: number]: boolean;
}
Con esta definición, cualquier variable de tipo IndieFable podrá ser accedida con un número entre corchetes, y TypeScript entenderá que el resultado es un booleano. Esto es útil cuando queremos garantizar que el acceso por índice siempre devuelva un tipo concreto, lo que ayuda a estructurar y controlar mejor los datos.
Además, no estamos limitados a índices numéricos. También podemos definir accesores indizados con índices de tipo string, lo que es especialmente útil para objetos que funcionan como mapas clave-valor. Por ejemplo, si queremos que al acceder con una cadena obtengamos un string, podemos definir:
interface IndieFable {
[key: string]: string;
}
Esto indica que cualquier acceso con una clave de tipo string devolverá un valor de tipo string. Es importante entender que esta característica se usa principalmente para especificar el tipo de retorno cuando accedemos mediante índices, más que para definir los tipos internos de las propiedades del objeto.
En definitiva, los accesores indizados en interfaces nos permiten expresar que un objeto o array debe soportar el acceso mediante índices y que el valor resultante debe ser de un tipo específico. Aunque puede parecer una peculiaridad, es una herramienta poderosa para definir contratos claros en nuestros tipos y evitar errores al acceder a datos mediante índices.