{}const=>[]async()letfn</>var
DesarrolloProfesiónWeb

Las preguntas más comunes en una entrevista de TypeScript

¿Te estás preparando para una entrevista de TypeScript? Analizamos las preguntas más populares que se hacen en las entrevistas: desde conceptos básicos hasta técnicas avanzadas. Generic, Type Guards, Utility Types, Mapped Types y mucho más con ejemplos de código y explicaciones.

К

Kodik

Autor

calendar_today
schedule10 min de lectura

¿Conoces ese momento en el que el reclutador escribe «se necesita un conocimiento básico de TypeScript» y en la entrevista te preguntan sobre la covarianza y la contravarianza? Sí, sí, todos hemos pasado por esto. Es hora de averiguar qué se pregunta realmente en las entrevistas de TypeScript y cómo responder para parecer una persona que ha leído no solo la documentación, sino también el código fuente del compilador (spoiler: no es necesario).

Vamos a analizar las preguntas más populares que les gusta hacer en las entrevistas. Pero no solo «qué es una interfaz», sino con situaciones reales y explicaciones de por qué a alguien le importa en absoluto.

1. «¿Cuál es la diferencia entre interface y type

Nivel de dificultad: parece fácil hasta que empiezas a responder

Es como preguntar «¿cuál es la diferencia entre una pizza y una pasta?». Ambas están hechas de masa, ambas son italianas, pero se sirven de forma diferente.

Respuesta corta para los impacientes:

  • interface - para objetos, se expande, se puede declarar varias veces (declaration merging)

  • type – para todo lo demás, incluyendo unión, intersección, primitivas

Respuesta detallada para la impresión:

// A la interfaz le gusta la herencia y la adición
interface User {
  name: string;
}

interface User {
  age: number; // ¡Se combina con el anterior!
}

// Type es un alias, no se puede redefinir
type Product = {
  id: number;
}

// type Product = { ... } // ❌ ¡Error!

// Pero type puede hacer cosas geniales:
type Status = 'pending' | 'success' | 'error';
type Response<T> = { data: T } | { error: string };

Qué decir en la entrevista: "En la práctica, utilizo interface para describir estructuras de datos que pueden expandirse (por ejemplo, tipos de API) y type para tipos de unión, utilidades y construcciones más complejas. La interfaz es mejor para los objetos gracias a la fusión de declaraciones».

🔥 100.000+ estudiantes ya están con nosotros

¿Cansado de leer teoría?
¡Hora de programar!

Kodik — una app donde aprendes a programar con práctica. Mentor IA, lecciones interactivas, proyectos reales.

🤖 IA 24/7
🎓 Certificados
💰 Gratis
🚀 Empezar
Se unieron hoy

2. «¿Qué son los genéricos y por qué son necesarios?»

Nivel de dificultad: Suena aterrador, pero en realidad es lógico

Los genéricos son como una plantilla en Word. Una vez escrito, sustituye cualquier dato.

// Sin Generic: dolor y sufrimiento
function getFirstElementString(arr: string[]): string {
  return arr[0];
}

function getFirstElementNumber(arr: number[]): number {
  return arr[0];
}

// Con Generic, una vez y para siempre
function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

const firstString = getFirstElement(['a', 'b']); // string
const firstNumber = getFirstElement([1, 2, 3]); // number

Nivel avanzado (para sorprender):

// Genérico con restricciones
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: 'Alexey', age: 25 };
getProperty(user, 'name'); // ✅ OK
getProperty(user, 'salary'); // ❌ ¡Error de compilación!

3. «Explica unknown vs any vs never»

Nivel de dificultad: Una cuestión filosófica en el mundo de los tipos

Imagina: any es "no me importa", unknown es "no lo sé, pero lo comprobaré", never es "esto no puede ser en absoluto".

// any - anarquía, haz lo que quieras
let chaos: any = 5;
chaos.doWhatever(); // Compilador: «Vale, tus problemas»
// desconocido - incertidumbre segura
let mystery: unknown = 5;
// mystery.doSomething(); // ❌ ¡Error!

// Primero, comprobemos
if (typeof mystery === 'number') {
  mystery.toFixed(2); // ✅ Ahora OK
}

// never - para código inalcanzable
function throwError(message: string): never {
  throw new Error(message);
  // El código nunca llegará aquí
}

type Shape = Circle | Square;
function getArea(shape: Shape) {
  switch(shape.kind) {
    case 'circle': return Math.PI * shape.radius ** 2;
    case 'square': return shape.size ** 2;
    default:
      const _exhaustive: never = shape; // Comprobación de la integridad
      return _exhaustive;
  }
}

Regla de oro: Utiliza unknown en lugar de any cuando no sepas el tipo. Tus compañeros te lo agradecerán.

4. «¿Qué son los tipos de utilidad y cuáles usas?»

Nivel de dificultad: muestra si has trabajado con proyectos reales

Utility Types son los ayudantes integrados de TypeScript. Es como una navaja suiza para los tipos.

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

// Parcial: todos los campos son opcionales
type UserUpdate = Partial<User>;
// { id?: number; name?: string; ... }

// Pick: seleccionar los campos necesarios
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: number; name: string }

// Omit - excluir campos
type UserPublic = Omit<User, 'password'>;
// { id: number; name: string; email: string }

// Record - creación de una estructura
type UserRoles = Record<'admin' | 'user' | 'guest', string[]>;
// { admin: string[]; user: string[]; guest: string[] }

// ReturnType - tipo de valor devuelto
function getUser() {
  return { id: 1, name: 'Alex' };
}
type User = ReturnType<typeof getUser>;

Truco para la entrevista: Menciona Readonly, Required, NonNullable para demostrar que no solo conoces los populares.

5. «¿Qué son los Type Guards y cómo se crean?»

Nivel de dificultad: Medio, pero muy práctico

Type Guards es una forma de convencer a TypeScript de que sabes qué tipo de datos tienes delante.

// Protección de tipo simple
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

// Más complejo
interface Cat {
  meow: () => void;
}

interface Dog {
  bark: () => void;
}

function isCat(animal: Cat | Dog): animal is Cat {
  return (animal as Cat).meow !== undefined;
}

function makeSound(animal: Cat | Dog) {
  if (isCat(animal)) {
    animal.meow(); // TypeScript sabe que es un gato
  } else {
    animal.bark(); // Y aquí - Dog
  }
}

// Usamos el operador 'in'
type Fish = { swim: () => void };
type Bird = { fly: () => void };

function move(animal: Fish | Bird) {
  if ('swim' in animal) {
    animal.swim();
  } else {
    animal.fly();
  }
}

6. «Cuéntame sobre keyof y typeof»

Nivel de dificultad: Aquí se separan los midles de los joons

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

// keyof - obtenemos la unión de todas las claves
type UserKeys = keyof User; // 'id' | 'name' | 'email'

// typeof - obtenemos el tipo del valor
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retries: 3
};

type Config = typeof config;
// { apiUrl: string; timeout: number; retries: number }

// Combo: keyof typeof
const Colors = {
  red: '#ff0000',
  blue: '#0000ff',
  green: '#00ff00'
} as const;

type ColorKey = keyof typeof Colors; // 'red' | 'blue' | 'green'

// Aplicación práctica
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

7. «¿Qué son los tipos asignados?»

Nivel de dificultad: Senior territory

Mapped Types es cuando conviertes un tipo en otro, como un alquimista.

type User = {
  name: string;
  age: number;
  email: string;
}

// Hacemos todos los campos readonly
type ReadonlyUser = {
  readonly [K in keyof User]: User[K];
};

// Hacemos que todos los campos sean opcionales
type PartialUser = {
  [K in keyof User]?: User[K];
};

// Hacemos todos los campos anulables
type NullableUser = {
  [K in keyof User]: User[K] | null;
};

// Creación de getters
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type UserGetters = Getters<User>;
// {
//   getName: () => string;
//   getAge: () => number;
//   getEmail: () => string;
// }

8. "¿Cuál es la diferencia entre los tipos enum y union?"

Nivel de dificultad: Una pregunta sencilla con truco

// Enum: crea un objeto JavaScript real
enum Status {
  Pending = 'PENDING',
  Success = 'SUCCESS',
  Error = 'ERROR'
}

console.log(Status.Pending); // ¡'PENDING' existe en tiempo de ejecución!

// Union - solo a nivel de tipo
type StatusUnion = 'PENDING' | 'SUCCESS' | 'ERROR';

// En runtime, es solo una línea
const status: StatusUnion = 'PENDING';

// Const enum - se compila en valores
const enum Direction {
  Up,
  Down,
  Left,
  Right
}

const dir = Direction.Up; // Se convertirá en 0

Qué decir: "Prefiero los tipos de unión para casos simples, ya que no agregan código de tiempo de ejecución. Utilizo Enum cuando necesito retroalimentación (mapeo inverso) o cuando los valores son necesarios en tiempo de ejecución».

9. «¿Qué son los tipos condicionales?»

Nivel de dificultad: Si lo entiendes, ya no eres un novato

Conditional Types es un operador ternario para tipos.

// Sintaxis básica
type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false

// Ejemplo práctico
type Flatten<T> = T extends Array<infer U> ? U : T;

type StrArray = Flatten<string[]>; // string
type Num = Flatten<number>; // number

// Más genial
type NonNullable<T> = T extends null | undefined ? never : T;

type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string

// Distributed Conditional Types
type ToArray<T> = T extends any ? T[] : never;
type StrOrNumArray = ToArray<string | number>;
// string[] | number[]

10. «Cuéntame sobre infer keyword»

Nivel de dificultad: Esto ya es magia

infer permite "extraer" un tipo de otro tipo.

// Obtenemos el tipo de valor de retorno de la función
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: 1, name: 'Alex' };
}

type User = ReturnType<typeof getUser>; // { id: number; name: string }

// Obtenemos el tipo de elemento de la matriz
type ArrayElement<T> = T extends (infer U)[] ? U : never;

type NumArray = number[];
type Num = ArrayElement<NumArray>; // number

// Obtenemos el tipo de parámetros de la función
type Parameters<T> = T extends (...args: infer P) => any ? P : never;

function createUser(name: string, age: number) {}

type CreateUserParams = Parameters<typeof createUser>; // [string, number]

// Promesas
type Awaited<T> = T extends Promise<infer U> ? U : T;

type AsyncResult = Awaited<Promise<string>>; // string

💡 ¿Cómo recordar todo esto y empezar a aplicarlo?

¿Honestamente? Leer artículos es genial, pero sin práctica, todo se olvidará en una semana. Realmente necesitas escribir código y enfrentar problemas.

Por eso hemos creado Kodik - una aplicación donde la teoría se convierte inmediatamente en práctica. Sin conferencias interminables, solo código y desafíos.

Además, tenemos Canal de Telegram con una comunidad de más de 2000 desarrolladores, donde todos los días hay publicaciones útiles, análisis de tareas, memes (dónde sin ellos) y discusiones. Es como Stack Overflow, pero de forma humana y en ruso.

Preguntas de bonificación que también pueden hacer:

11. «¿Qué es la fusión de declaraciones?»

interface Box {
  height: number;
}

interface Box {
  width: number;
}

// TypeScript combinará ambos en:
// interface Box {
//   height: number;
//   width: number;
// }

12. «¿Por qué es necesario as const

// Sin as const
const colors = ['red', 'blue']; // string[]

// Con as const
const colorsConst = ['red', 'blue'] as const; // readonly ['red', 'blue']

// Aplicación práctica
const routes = {
  home: '/',
  about: '/about',
  contact: '/contact'
} as const;

type Route = typeof routes[keyof typeof routes]; 
// '/' | '/about' | '/contact'

13. «¿Qué son los tipos de plantillas literales?»

type Direction = 'up' | 'down' | 'left' | 'right';
type Move = `move${Capitalize<Direction>}`; 
// 'moveUp' | 'moveDown' | 'moveLeft' | 'moveRight'

type EventName = 'click' | 'focus' | 'blur';
type Handler = `on${Capitalize<EventName>}`;
// 'onClick' | 'onFocus' | 'onBlur'

Conclusión: cómo prepararse para la entrevista

Una semana antes:

  1. Revisa la documentación oficial de TypeScript

  2. Resuelve los desafíos en Type Challenges (github.com/type-challenges/type-challenges)

  3. Practica explicar los conceptos en voz alta

El día antes de:

  1. Repite los conceptos básicos de este artículo

  2. Prepara ejemplos de tus proyectos

  3. Duerme lo suficiente (en serio, es más importante que estudiar)

En la entrevista:

  • No tengas miedo de decir «no lo sé, pero puedo buscarlo»

  • Es mejor explicar el concepto con tus propias palabras que citar la documentación

  • Haz preguntas aclaratorias: esto demuestra que estás pensando

Lo principal: TypeScript es una herramienta, no un fin en sí mismo. Entender ¿Por qué? necesita tipificación, es más importante que saberse de memoria todos los tipos de servicios públicos.

P.S. Si después de leerlo tienes la cabeza hecha un lío, es normal. TypeScript no es algo que se aprenda de la noche a la mañana. Vuelve a este artículo, prueba ejemplos, comete errores y aprende. Así es como funciona todo.

¡Buena suerte con las entrevistas! Que el compilador te acompañe ✨

🎯Deja de postergar

¿Te gustó el artículo?
¡Hora de practicar!

En Kodik no solo lees — escribes código de inmediato. Teoría + práctica = habilidades reales.

Práctica instantánea
🧠IA explica código
🏆Certificado

Sin registro • Sin tarjeta