Convertir un objeto de un tipo de interfaz parcial al tipo de interfaz "completo" en TypeScript
Digamos que tengo una interfaz A que se ve así:
interface A {
prop1: string
prop2: string
}
Inicializo el objeto obj así:
const obj: Partial<A> = { prop1: 'xyz' }
¿Hay alguna manera de convertir obj a A y establecer automáticamente cualquier propiedad no definida en obj pero requerida en A a null o undefined? Me gustaría usar solo parciales en la inicialización de una variable si es posible, y mantenerme en el tipo "completo" en los parámetros de función.
No puedo cambiar A para que sea una clase.
Respuesta #1
Esta respuesta es bastante tardía, pero la dejaré por si alguien la encuentra más tarde.
Typescript se trata de tipos, que se utilizan en tiempo de compilación para verificar si el código es correcto, pero se eliminan en tiempo de ejecución para convertir el código en JavaScript puro. Esto significa que no hay forma de agregar ninguna propiedad usando las funciones de Typescript.
Sin embargo, puedes definir una función que tome un objeto parcial y establezca propiedades por defecto:
function complete(obj: Partial<A>): A {
return Object.assign({
prop1: 'default1',
prop2: 'default2'
}, obj);
}
const partial: Partial<A> = { prop1: 'xyz' }
const a: A = complete(partial)
console.log(a) // { prop1: 'xyz', prop2: 'default2' }
Si quieres establecer propiedades faltantes como undefined, la misma función funcionará, pero no podrás convertir el objeto devuelto a A, porque A requiere que todas las propiedades sean cadenas y no null o undefined
Respuesta #2
Como una extensión de la buena respuesta de Alex Chashin, aquí hay una variación donde el objetivo es validar que un Partial<T> es un T válido y convertirlo de manera segura a él, de lo contrario devolver undefined.
El obj se pasa como el primer parámetro de Object.assign (target) para mantener la integridad referencial. El segundo parámetro realiza una fusión (inofensiva) y asegura que el resultado será un T válido gracias a la condición if.
interface A {
value1: string
value2: string
}
function validateObject(obj: Partial<A>): A | undefined {
if (obj.value1 && obj.value2) {
// Safe cast Partial<T> to T
return Object.assign(obj, {
value1: obj.value1,
value2: obj.value2,
});
}
return undefined;
}
