TypeScript: Utility Types Avanzados que Debes Conocer
9 de diciembre de 2025
Osman Jimenez
TypeScript Desarrollo Web Programación
Dominando los Utility Types de TypeScript
TypeScript incluye tipos de utilidad poderosos que pueden transformar y manipular tipos existentes. Estos son esenciales para escribir código type-safe y mantenible.
Utility Types Básicos
Partial y Required
interface User {
id: number;
name: string;
email: string;
age: number;
}
// Partial: Hace todas las propiedades opcionales
type PartialUser = Partial;
// { id?: number; name?: string; email?: string; age?: number; }
// Required: Hace todas las propiedades requeridas
type RequiredUser = Required;
// { id: number; name: string; email: string; age: number; } Pick y Omit
// Pick: Selecciona propiedades específicas
type UserPreview = Pick;
// { id: number; name: string; }
// Omit: Excluye propiedades específicas
type UserWithoutAge = Omit;
// { id: number; name: string; email: string; } Utility Types Avanzados
Record
// Record: Crea un objeto con claves y valores específicos
type UserRoles = 'admin' | 'user' | 'guest';
type RolePermissions = Record;
const permissions: RolePermissions = {
admin: ['read', 'write', 'delete'],
user: ['read', 'write'],
guest: ['read']
}; ReturnType y Parameters
function createUser(name: string, age: number) {
return { name, age, createdAt: new Date() };
}
// ReturnType: Extrae el tipo de retorno
type User = ReturnType;
// { name: string; age: number; createdAt: Date; }
// Parameters: Extrae los tipos de parámetros
type CreateUserParams = Parameters;
// [name: string, age: number] Awaited
type AsyncUser = Promise<{ id: number; name: string }>;
// Awaited: Desenvuelve el tipo de una Promise
type User = Awaited;
// { id: number; name: string; } Utility Types Personalizados
DeepPartial
type DeepPartial = {
[P in keyof T]?: T[P] extends object
? DeepPartial
: T[P];
};
interface Config {
database: {
host: string;
port: number;
credentials: {
user: string;
password: string;
};
};
}
type PartialConfig = DeepPartial;
// Todas las propiedades anidadas son opcionales Nullable y NonNullable
type Nullable = T | null | undefined;
type NonNullable = T extends null | undefined ? never : T;
type MaybeString = Nullable;
// string | null | undefined
type DefiniteString = NonNullable;
// string ReadonlyDeep
type ReadonlyDeep = {
readonly [P in keyof T]: T[P] extends object
? ReadonlyDeep
: T[P];
};
interface MutableConfig {
settings: {
theme: string;
language: string;
};
}
type ImmutableConfig = ReadonlyDeep;
// Todas las propiedades son readonly recursivamente Conditional Types
// Extrae tipos de arrays
type ArrayElement = T extends (infer E)[] ? E : never;
type Numbers = ArrayElement; // number
type Strings = ArrayElement; // string
// Filtra tipos
type FilterByType = {
[K in keyof T as T[K] extends U ? K : never]: T[K];
};
interface Mixed {
id: number;
name: string;
age: number;
active: boolean;
}
type OnlyNumbers = FilterByType;
// { id: number; age: number; } Template Literal Types
type EventName = 'click' | 'focus' | 'blur';
type EventHandler = `on${Capitalize}`;
// 'onClick' | 'onFocus' | 'onBlur'
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type Endpoint = `/api/${Lowercase}`;
// '/api/get' | '/api/post' | '/api/put' | '/api/delete' Casos de Uso Prácticos
Form State Management
type FormState = {
values: T;
errors: Partial>;
touched: Partial>;
isValid: boolean;
};
interface LoginForm {
email: string;
password: string;
}
const formState: FormState = {
values: { email: '', password: '' },
errors: {},
touched: {},
isValid: false
}; API Response Types
type ApiResponse =
| { success: true; data: T }
| { success: false; error: string };
type UserResponse = ApiResponse;
function handleResponse(response: UserResponse) {
if (response.success) {
console.log(response.data); // Type: User
} else {
console.error(response.error); // Type: string
}
} Mejores Prácticas
- Usa utility types nativos: Antes de crear uno personalizado
- Mantén tipos simples: La complejidad excesiva dificulta el mantenimiento
- Documenta tipos complejos: Usa comentarios JSDoc
- Reutiliza tipos: Crea una librería de utility types para tu proyecto
- Testing de tipos: Usa herramientas como tsd para validar tipos
Conclusión
Los utility types de TypeScript son herramientas poderosas que te permiten manipular y transformar tipos de forma elegante. Dominarlos te ayudará a escribir código más seguro, mantenible y expresivo.