javascript - Typescript - iki arayüz arasındaki ortak özelliklerle nasıl başa çıkarsınız?
Bir interfaceA1 ve bazı ortak özelliklere sahip interfaceB'im var
interface A1 {
id : string,
version: number,
data: userData,
createdBy: string
}
interface userData {
data: string,
status: string
}
interface B {
id : string,
version: number,
definition : JSON
}
Yani, interfaceA1 ve interfaceB arasında id, version gibi bazı ortak özellikler vardır.
Aşağıdaki değerlere sahip interfaceA türünde bir değişkenim var
let interfaceA1Data: interfaceA1 = {
id : '123abc',
version: 1,
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
Sadece deklarasyonu yapılmış başka bir interfaceB türünde değişkenim var
let interfaceBData: interfaceB
Şimdi, interfaceA1Data'dan interfaceBData'ya ortak özelliklerin değerlerini kopyalamak istiyorum. Ortak olmayan özellikler definition özelliğine eklenmelidir. Yani, sonunda interfaceBData aşağıdaki değerleri tutacak.
interfaceBData = {
id : '123abc',
version: 1,
definition: {
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
}
Bunu TypeScript'te nasıl başarabilirim?
Dönüştürücü genel olmalıdır, diyelim ki interfaceA2'im var, bunu interfaceB tipine nasıl dönüştürebilirim. Tüm durumlarda hedef arayüz aynıdır, sadece kaynak arayüz farklıdır.
interface A2 {
id : string,
version: number,
value: valueType,
createdBy: string
}
interface valueType {
type: string,
requester: string
}
Cevap #1
İki arayüz arasında kasıtlı bir örtüşme varsa, ortak özellikleri ayrı bir arayüze çıkarmak faydalı olabilir. Örneğin:
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
}
Şimdi, daha önce yaptığınız gibi, sadece definition özelliğini Nesne olarak ekleyerek Versioned'i bir kez daha genişleterek 'B' arayüzünü oluşturma yoluna gidebilirsiniz:
interface B extends Versioned {
definition: Object
}
... ancak bunu bunun yerine genel bir arayüze dönüştürerek ek katılık sağlamayı düşünebilirsiniz, şöyle:
interface Serialized<T extends Versioned> extends Versioned {
definition: Omit<T, keyof Versioned>
}
Artık Versioned'i genişleten herhangi bir tür/arayüz için bir dönüştürücü fonksiyonu kolayca yazabilir ve bunu Serialized'ın belirli şekline dönüştürebilirsiniz:
function transformer<T extends Versioned>(
{id, version, ...args}: T): Serialized<T> {
return {
id, version,
definition: {...args}
}
}
İşte TS Playground bağlantısı.
