[Easy] Tipos básicos y anotaciones de tipo
1. What are TypeScript Basic Types?
Cuáles son los tipos básicos de TypeScript?
TypeScript proporciona una variedad de tipos básicos para definir los tipos de variables, parámetros de funciones y valores de retorno.
Tipos básicos
// 1. number: números (enteros, punto flotante)
let age: number = 30;
let price: number = 99.99;
// 2. string: cadenas de texto
let name: string = 'John';
let message: string = `Hello, ${name}!`;
// 3. boolean: valores booleanos
let isActive: boolean = true;
let isCompleted: boolean = false;
// 4. null: valor nulo
let data: null = null;
// 5. undefined: no definido
let value: undefined = undefined;
// 6. void: sin valor de retorno (usado principalmente en funciones)
function logMessage(): void {
console.log('Hello');
}
// 7. any: cualquier tipo (debe evitarse)
let anything: any = 'hello';
anything = 42;
anything = true;
// 8. unknown: tipo desconocido (más seguro que any)
let userInput: unknown = 'hello';
// userInput.toUpperCase(); // ❌ Error: se debe verificar el tipo primero
// 9. never: valor que nunca ocurre (para funciones que nunca retornan)
function throwError(): never {
throw new Error('Error');
}
// 10. object: objeto (poco usado, se recomienda usar interface)
let user: object = { name: 'John' };
// 11. array: arreglo
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ['John', 'Jane'];
// 12. tuple: tupla (arreglo de longitud y tipos fijos)
let person: [string, number] = ['John', 30];
2. Type Annotations vs Type Inference
Anotaciones de tipo vs Inferencia de tipo
Anotaciones de tipo (Type Annotations)
Definición: Especificar explícitamente el tipo de una variable.
// Especificar el tipo explícitamente
let age: number = 30;
let name: string = 'John';
let isActive: boolean = true;
// Parámetros de función y valores de retorno
function add(a: number, b: number): number {
return a + b;
}
Inferencia de tipo (Type Inference)
Definición: TypeScript infiere automáticamente el tipo basado en el valor inicial.
// TypeScript infiere automáticamente como number
let age = 30; // age: number
// TypeScript infiere automáticamente como string
let name = 'John'; // name: string
// TypeScript infiere automáticamente como boolean
let isActive = true; // isActive: boolean
// Los valores de retorno de funciones también se infieren automáticamente
function add(a: number, b: number) {
return a + b; // El valor de retorno se infiere automáticamente como number
}
Cuándo usar anotaciones de tipo
Situaciones en las que se debe especificar el tipo explícitamente:
// 1. Declaración de variable sin valor inicial
let value: number;
value = 10;
// 2. Parámetros de función (obligatorio)
function greet(name: string): void {
console.log(`Hello, ${name}!`);
}
// 3. Valor de retorno de función (se recomienda especificar explícitamente)
function calculate(): number {
return 42;
}
// 4. Tipos complejos donde la inferencia puede no ser precisa
let data: { name: string; age: number } = {
name: 'John',
age: 30,
};
3. Common Interview Questions
Preguntas frecuentes en entrevistas
Pregunta 1: Inferencia de tipo
Explique el tipo de cada variable en el siguiente código.
let value1 = 10;
let value2 = 'hello';
let value3 = true;
let value4 = [1, 2, 3];
let value5 = { name: 'John', age: 30 };
Haga clic para ver la respuesta
let value1 = 10; // number
let value2 = 'hello'; // string
let value3 = true; // boolean
let value4 = [1, 2, 3]; // number[]
let value5 = { name: 'John', age: 30 }; // { name: string; age: number }
Explicación:
- TypeScript infiere automáticamente el tipo basado en el valor inicial
- Los arreglos se infieren como arreglo del tipo de sus elementos
- Los objetos se infieren como el tipo estructural del objeto
Pregunta 2: Errores de tipo
Encuentre los errores de tipo en el siguiente código.
let age: number = 30;
age = 'thirty';
let name: string = 'John';
name = 42;
let isActive: boolean = true;
isActive = 'yes';
let numbers: number[] = [1, 2, 3];
numbers.push('4');
Haga clic para ver la respuesta
let age: number = 30;
age = 'thirty'; // ❌ Type 'string' is not assignable to type 'number'
let name: string = 'John';
name = 42; // ❌ Type 'number' is not assignable to type 'string'
let isActive: boolean = true;
isActive = 'yes'; // ❌ Type 'string' is not assignable to type 'boolean'
let numbers: number[] = [1, 2, 3];
numbers.push('4'); // ❌ Argument of type 'string' is not assignable to parameter of type 'number'
Forma correcta de escribirlo:
let age: number = 30;
age = 30; // ✅
let name: string = 'John';
name = 'Jane'; // ✅
let isActive: boolean = true;
isActive = false; // ✅
let numbers: number[] = [1, 2, 3];
numbers.push(4); // ✅
Pregunta 3: any vs unknown
Explique la diferencia entre any y unknown, e indique cuál debería usarse.
// Caso 1: usando any
function processAny(value: any): void {
console.log(value.toUpperCase()); // ?
}
// Caso 2: usando unknown
function processUnknown(value: unknown): void {
console.log(value.toUpperCase()); // ?
}
Haga clic para ver la respuesta
Caso 1: usando any
function processAny(value: any): void {
console.log(value.toUpperCase()); // ⚠️ Compila correctamente, pero puede fallar en tiempo de ejecución
}
processAny('hello'); // ✅ Ejecución normal
processAny(42); // ❌ Error en tiempo de ejecución: value.toUpperCase is not a function
Caso 2: usando unknown
function processUnknown(value: unknown): void {
// console.log(value.toUpperCase()); // ❌ Error de compilación: Object is of type 'unknown'
// Se debe verificar el tipo primero
if (typeof value === 'string') {
console.log(value.toUpperCase()); // ✅ Seguro
}
}
Comparación de diferencias:
| Característica | any | unknown |
|---|---|---|
| Verificación de tipos | Completamente desactivada | Requiere verificación antes de usar |
| Seguridad | Inseguro | Seguro |
| Recomendación | Evitar su uso | Recomendado |
Mejores prácticas:
// ✅ Recomendado: usar unknown y verificar el tipo
function processValue(value: unknown): void {
if (typeof value === 'string') {
console.log(value.toUpperCase());
} else if (typeof value === 'number') {
console.log(value.toFixed(2));
}
}
// ❌ Evitar: usar any
function processValue(value: any): void {
console.log(value.toUpperCase()); // Inseguro
}
Pregunta 4: Tipos de arreglo
Explique las diferencias en las siguientes declaraciones de tipos de arreglo.
let arr1: number[];
let arr2: Array<number>;
let arr3: [number, string];
let arr4: any[];
Haga clic para ver la respuesta
// 1. number[]: arreglo de números (escritura recomendada)
let arr1: number[] = [1, 2, 3];
arr1.push(4); // ✅
arr1.push('4'); // ❌ Error
// 2. Array<number>: arreglo genérico (equivalente a number[])
let arr2: Array<number> = [1, 2, 3];
arr2.push(4); // ✅
arr2.push('4'); // ❌ Error
// 3. [number, string]: tupla (Tuple) - longitud y tipos fijos
let arr3: [number, string] = [1, 'hello'];
arr3[0] = 2; // ✅
arr3[1] = 'world'; // ✅
arr3[2] = true; // ❌ Error: longitud excede 2
arr3.push('test'); // ⚠️ TypeScript lo permite, pero no se recomienda
// 4. any[]: arreglo de cualquier tipo (no recomendado)
let arr4: any[] = [1, 'hello', true];
arr4.push(42); // ✅
arr4.push('world'); // ✅
arr4.push(false); // ✅ (pero se pierde la verificación de tipos)
Recomendaciones de uso:
- Arreglos generales: usar
number[]oArray<number> - Estructura fija: usar tupla
[type1, type2] - Evitar
any[], preferir tipos concretos ounknown[]
Pregunta 5: void vs never
Explique las diferencias y casos de uso de void y never.
// Caso 1: void
function logMessage(): void {
console.log('Hello');
}
// Caso 2: never
function throwError(): never {
throw new Error('Error');
}
function infiniteLoop(): never {
while (true) {
// Bucle infinito
}
}
Haga clic para ver la respuesta
void:
- Uso: Indica que una función no retorna un valor
- Característica: La función termina normalmente, simplemente no retorna un valor
- Casos de uso: Manejadores de eventos, funciones con efectos secundarios
function logMessage(): void {
console.log('Hello');
// La función termina normalmente, no retorna un valor
}
function onClick(): void {
// Maneja el evento de clic, no necesita valor de retorno
}
never:
- Uso: Indica que una función nunca termina normalmente
- Característica: La función lanza un error o entra en un bucle infinito
- Casos de uso: Manejo de errores, bucles infinitos, type guards
function throwError(): never {
throw new Error('Error');
// Nunca se llega aquí
}
function infiniteLoop(): never {
while (true) {
// Nunca termina
}
}
// Uso en type guards
function assertNever(value: never): never {
throw new Error(`Unexpected value: ${value}`);
}
Comparación de diferencias:
| Característica | void | never |
|---|---|---|
| Fin de función | Termina normalmente | Nunca termina |
| Valor de retorno | undefined | Sin valor de retorno |
| Casos de uso | Funciones sin valor de retorno | Manejo de errores, bucles infinitos |
4. Best Practices
Mejores prácticas
Prácticas recomendadas
// 1. Preferir la inferencia de tipo
let age = 30; // ✅ Dejar que TypeScript infiera
let name = 'John'; // ✅
// 2. Especificar explícitamente el tipo de parámetros y retorno de funciones
function calculate(a: number, b: number): number {
return a + b;
}
// 3. Usar unknown en lugar de any
function processValue(value: unknown): void {
if (typeof value === 'string') {
console.log(value.toUpperCase());
}
}
// 4. Usar tipos de arreglo específicos
let numbers: number[] = [1, 2, 3]; // ✅
let names: Array<string> = ['John', 'Jane']; // ✅
// 5. Usar tuplas para estructuras fijas
let person: [string, number] = ['John', 30]; // ✅
Prácticas a evitar
// 1. Evitar el uso de any
let value: any = 'hello'; // ❌
// 2. Evitar anotaciones de tipo innecesarias
let age: number = 30; // ⚠️ Se puede simplificar a let age = 30;
// 3. Evitar el tipo object
let user: object = { name: 'John' }; // ❌ Es mejor usar interface
// 4. Evitar arreglos de tipos mixtos (a menos que sea necesario)
let mixed: (string | number)[] = ['hello', 42]; // ⚠️ Considerar si realmente es necesario
5. Interview Summary
Resumen para entrevistas