Introducción: ¿Por qué necesitas las claves de la interfaz como un array?
Imagina: estás trabajando en un proyecto grande con TypeScript y necesitas recorrer todos los campos de un objeto complejo, crear un formulario dinámico en React, filtrar datos o simplemente mostrar una lista de propiedades disponibles. El problema es que TypeScript es una extensión de JavaScript, y sus tipos solo existen durante la compilación. En tiempo de ejecución, desaparecen. ¿Qué hacer? ¿Cómo obtener las claves de una interfaz de TypeScript como un array de strings para usarlas en código real?
Una pregunta que atormenta a miles de desarrolladores en Stack Overflow. Hoy, en 2025, analizaremos todos los enfoques posibles: desde los simples y confiables hasta los avanzados. Aprenderás cómo hacer que TypeScript trabaje para ti, no en tu contra. ¡Allá vamos!
El problema: Tipos "desaparecidos"
Veamos directamente la raíz del problema. Supongamos que tienes esta interfaz:
interface User { id: number; name: string; email: string; isAdmin: boolean;}Necesitas obtener un array de strings: ['id', 'name', 'email', 'isAdmin']. Lo primero que viene a la mente es usar Object.keys(). Pero hay un detalle. Si intentas escribir esto:
const keys = Object.keys({} as User);// Tipo: string[]TypeScript devolverá el tipo string[], no ('id' | 'name' | 'email' | 'isAdmin')[]. Esto no tiene sentido: pierdes toda la información sobre las claves específicas.
¿Por qué sucede esto? Porque Object.keys() en JavaScript siempre devuelve un array de strings. TypeScript no puede saber con certeza qué claves tendrá el objeto en tiempo de ejecución (por ejemplo, si el objeto se expande). Por lo tanto, proporciona el tipo más seguro, pero inútil.
Solución 1: Array "manual" (Simplicidad y seguridad)
La forma más simple y recomendada para el 90% de los casos es crear un array manualmente y derivar el tipo a partir de él. No es una broma. Este enfoque garantiza que tu array siempre esté sincronizado con la interfaz.
// 1. Definimos el array de clavesexport const USER_KEYS = ['id', 'name', 'email', 'isAdmin'] as const;
// 2. Derivamos el tipo del arraytype UserKey = typeof USER_KEYS[number]; // 'id' | 'name' | 'email' | 'isAdmin'
// 3. Lo usamos para la interfazinterface User { [key in UserKey]: key extends 'id' ? number : key extends 'name' ? string : key extends 'email' ? string : boolean;}
// 4. Obtenemos el array de stringsconst keys: string[] = [...USER_KEYS];console.log(keys); // ['id', 'name', 'email', 'isAdmin']Ventajas: Tipificación completa, sin trucos mágicos, fácil de leer y mantener.
Desventajas: Necesitas mantener dos lugares (interfaz y array) manualmente.
Solución 2: Tipo utilitario con keyof (Avanzado, pero con salvedades)
TypeScript proporciona el operador keyof, que devuelve una unión de claves (union type). Pero, ¿cómo convertir esa unión en un array de strings? En 2025, esto todavía requiere un pequeño truco.
La forma clásica es usar una función auxiliar que verifique los tipos durante la compilación:
// Función auxiliarfunction getKeys<T>(obj: T): (keyof T)[] { return Object.keys(obj) as (keyof T)[];}
// Usointerface Product { title: string; price: number; inStock: boolean;}
const product: Product = { title: 'Keyboard', price: 100, inStock: true};
const productKeys = getKeys(product);// Tipo: ("title" | "price" | "inStock")[]console.log(productKeys); // ['title', 'price', 'inStock']Importante: Este método solo funciona si tienes un objeto real que coincida con la interfaz. Si solo tienes la interfaz, pero no el objeto, tendrás que cre