Cómo establecer un valor predeterminado para un objeto TypeScript en un argumento: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué se busca esto con tanta frecuencia?

\n\n

Cada desarrollador que migra de JavaScript a TypeScript o simplemente escribe en este lenguaje, tarde o temprano se enfrenta al problema: ¿cómo establecer correctamente un valor predeterminado para un objeto que se pasa a una función? En Stack Overflow, esta pregunta ha acumulado miles de visitas y decenas de respuestas. ¿Por qué? Porque, aunque parece una tarea simple — "si no se pasa un objeto, usa un objeto vacío" — en TypeScript se convierte en toda una odisea con tipos, interfaces y desestructuración.

\n\n

En este artículo, analizaremos todas las formas posibles, desde las más simples hasta las más avanzadas, con ejemplos de código y explicaciones. Aprenderá cómo configurar valores predeterminados para un objeto TypeScript pasado como argumento y evitar errores típicos. ¡Allá vamos!

\n\n

El problema: ¿qué tiene de malo el enfoque habitual?

\n\n

Supongamos que tenemos una función que recibe un objeto con configuraciones:

\n\n
function createUser(config: { name?: string; age?: number }) {\n  // ...\n}\n\ncreateUser(); // ¡Error! Se necesita un argumento\n
\n\n

En JavaScript, simplemente podríamos escribir function createUser(config = {}) y listo. Pero en TypeScript, este truco no funciona: el compilador se quejará por la falta de coincidencia de tipos. ¿Por qué? Porque el objeto vacío {} no coincide con la interfaz { name?: string; age?: number } — simplemente no tiene esas propiedades.

\n\n

Y aquí es donde comienza lo interesante. Analicemos todas las formas de resolverlo.

\n\n

Forma 1: Desestructuración con asignación de valores predeterminados

\n\n

El método más elegante y popular es usar la desestructuración directamente en los parámetros de la función. Extrae las propiedades del objeto y les asigna valores predeterminados de inmediato:

\n\n
function createUser({ name = "Invitado", age = 18 }: { name?: string; age?: number } = {}) {\n  console.log(`Usuario creado: ${name}, edad: ${age}`);\n}\n\ncreateUser(); // "Usuario creado: Invitado, edad: 18"\ncreateUser({ name: "Ana" }); // "Usuario creado: Ana, edad: 18"\ncreateUser({ age: 25 }); // "Usuario creado: Invitado, edad: 25"\n
\n\n

Observe el = {} al final. Este es el valor predeterminado para el objeto en sí. Si no pasa un argumento, TypeScript usa un objeto vacío y la desestructuración asigna los valores predeterminados para cada propiedad.

\n\n

Ventajas: limpio, conciso, funciona como un reloj.
\nDesventajas: es necesario especificar explícitamente el tipo para cada propiedad.

\n\n

Forma 2: Uso de una interfaz con Partial

\n\n

Si su objeto es grande, describir todos los tipos en los parámetros es de mala educación. Saque la interfaz por separado y use Partial<T>:

\n\n
interface UserConfig {\n  name: string;\n  age: number;\n  email: string;\n  isAdmin: boolean;\n}\n\nfunction createUser(config: Partial<UserConfig> = {}) {\n  const defaults: UserConfig = {\n    name: "Invitado",\n    age: 18,\n    email: "noemail@example.com",\n    isAdmin: false\n  };\n  \n  const mergedConfig = { ...defaults, ...config };\n  console.log(mergedConfig);\n}\n\ncreateUser({ name: "Iván" });\n// { name: "Iván", age: 18, email: "noemail@example.com", isAdmin: false }\n
\n\n

Aquí, Partial<UserConfig> hace que todas las propiedades sean opcionales. Dentro de la función, fusionamos los valores predeterminados con los pasados. Funciona perfectamente, pero requiere una fusión manual.

\n\n

Forma 3: Enfoque clásico con verificación

\n\n

A veces se necesita más control. Por ejemplo, si desea establecer un valor predeterminado solo para undefined, pero no para null. Usamos el clásico if:

\n\n
function createUser(config?: UserConfig) {\n  const name = config?.name ?? "Invitado";\n  const age = config?.age ?? 18;\n  const email = config?.email ?? "noemail@example.com";\n  \n  console.log({ name, age, email });\n}\n\ncreateUser();                

Blogs

Book Recommendations