I have an interfaceA1 and interfaceB with some properties in common
interface A1 {
id : string,
version: number,
data: userData,
createdBy: string
}
interface userData {
data: string,
status: string
}
interface B {
id : string,
version: number,
definition : JSON
}
So, there are some properties like id, version is common between interfaceA1 and interfaceB
I have variable of type interfaceA with following values
let interfaceA1Data: interfaceA1 = {
id : '123abc',
version: 1,
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
I have another variable of type interfaceB, that is just declared
let interfaceBData: interfaceB
Now I want to copy the values of common properties from interfaceA1Data to interfaceBData. The non-common properties should be added to the definition property. So, in the end the interfaceBData will hold the following values.
interfaceBData = {
id : '123abc',
version: 1,
definition: {
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
}
How to achieve this in typescript?
The transformer should be generic say if I have an interfaceA2, how to convert to interfaceB type. In all the case destination interface is same only the source interface differs.
interface A2 {
id : string,
version: number,
value: valueType,
createdBy: string
}
interface valueType {
type: string,
requester: string
}
If there's an intentional overlap between two interfaces, it might be worth extracting common properties into a separate interface. For example:
interface Versioned {
id: string,
version: number
}
interface userData {
data: string,
status: string
}
interface valueType {
type: string,
requester: string
}
interface A1 extends Versioned {
data: userData,
createdBy: string
}
interface A2 extends Versioned {
value: valueType,
createdBy: string
}
Now, you can either proceed with creating 'B' interface the same way you did before, just by extending Versioned once more with definition property as Object:
interface B extends Versioned {
definition: Object
}
... but you might want to provide additional strictness by turning it into generic interface instead, like this:
interface Serialized<T extends Versioned> extends Versioned {
definition: Omit<T, keyof Versioned>
}
Now you can easily write a transformer function for any type/interface extending Versioned turning this into specific shape of Serialized:
function transformer<T extends Versioned>(
{id, version, ...args}: T): Serialized<T> {
return {
id, version,
definition: {...args}
}
}
Here's TS Playground link.