javascript - Typescript - como você lida com propriedades comuns entre duas interfaces?
Eu tenho uma interfaceA1 e interfaceB com algumas propriedades em comum
interface A1 {
id : string,
version: number,
data: userData,
createdBy: string
}
interface userData {
data: string,
status: string
}
interface B {
id : string,
version: number,
definition : JSON
}
Então, existem algumas propriedades como id, versão que são comuns entre interfaceA1 e interfaceB
Eu tenho uma variável do tipo interfaceA com os seguintes valores
let interfaceA1Data: interfaceA1 = {
id : '123abc',
version: 1,
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
Eu tenho outra variável do tipo interfaceB, que está apenas declarada
let interfaceBData: interfaceB
Agora eu quero copiar os valores das propriedades comuns de interfaceA1Data para interfaceBData. As propriedades não comuns devem ser adicionadas à propriedade definition. Assim, no final, o interfaceBData terá os seguintes valores.
interfaceBData = {
id : '123abc',
version: 1,
definition: {
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
}
Como alcançar isso em TypeScript?
O transformador deve ser genérico, digamos que eu tenha uma interfaceA2, como converter para o tipo interfaceB. Em todos os casos, a interface de destino é a mesma, apenas a interface de origem difere.
interface A2 {
id : string,
version: number,
value: valueType,
createdBy: string
}
interface valueType {
type: string,
requester: string
}
Resposta #1
Se houver uma sobreposição intencional entre duas interfaces, pode ser válido extrair propriedades comuns para uma interface separada. Por exemplo:
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
}
Agora, você pode prosseguir criando a interface 'B' da mesma forma que fez antes, apenas estendendo Versioned mais uma vez com a propriedade definition como Objeto:
interface B extends Versioned {
definition: Object
}
... mas você pode querer fornecer maior rigor transformando-o em uma interface genérica, assim:
interface Serialized<T extends Versioned> extends Versioned {
definition: Omit<T, keyof Versioned>
}
Agora você pode facilmente escrever uma função transformadora para qualquer tipo/interface que estenda Versioned, transformando isso em uma forma específica de Serialized:
function transformer<T extends Versioned>(
{id, version, ...args}: T): Serialized<T> {
return {
id, version,
definition: {...args}
}
}
Aqui está o link do TS Playground.
