javascript - Typescript - איך אתה מתמודד עם תכונות משותפות בין שתי ממשקים?
יש לי ממשק A1 וממשק B עם כמה תכונות משותפות
interface A1 {
id : string,
version: number,
data: userData,
createdBy: string
}
interface userData {
data: string,
status: string
}
interface B {
id : string,
version: number,
definition : JSON
}
אז, יש כמה תכונות כמו id ו-version שמשותפות בין interfaceA1 ל-interfaceB
יש לי משתנה מסוג interfaceA עם הערכים הבאים
let interfaceA1Data: interfaceA1 = {
id : '123abc',
version: 1,
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
יש לי משתנה נוסף מסוג interfaceB, שהוא רק הוכרז
let interfaceBData: interfaceB
עכשיו אני רוצה להעתיק את הערכים של התכונות המשותפות מ-interfaceA1Data ל-interfaceBData. התכונות שאינן משותפות צריכות להיות מתווספות לתכונת definition. כך, בסופו של דבר interfaceBData יחזיק את הערכים הבאים.
interfaceBData = {
id : '123abc',
version: 1,
definition: {
data: {
data: 'value',
status: 'value'
},
createdBy: 'me'
}
}
איך להשיג את זה ב-TypeScript?
הטרנספורמר צריך להיות גנרי, נניח אם יש לי interfaceA2, איך להמיר לסוג interfaceB. בכל המקרים הממשק היעד הוא אותו דבר רק הממשק המקור שונה.
interface A2 {
id : string,
version: number,
value: valueType,
createdBy: string
}
interface valueType {
type: string,
requester: string
}
תשובה #1
אם יש חפיפה מכוונת בין שני ממשקים, ייתכן ששווה להוציא את המאפיינים המשותפים לממשק נפרד. לדוגמה:
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
}
עכשיו, אתה יכול להמשיך וליצור את הממשק 'B' באותה הדרך שעשית קודם, פשוט על ידי הרחבת Versioned פעם נוספת עם המאפיין definition כאובייקט:
interface B extends Versioned {
definition: Object
}
... אבל ייתכן שתרצה להוסיף קפדנות נוספת על ידי הפיכתו לממשק גנרי במקום זאת, כך:
interface Serialized<T extends Versioned> extends Versioned {
definition: Omit<T, keyof Versioned>
}
כעת ניתן בקלות לכתוב פונקציית טרנספורמר לכל סוג/ממשק שמרחיב את Versioned ולהפוך זאת לצורה ספציפית של Serialized:
function transformer<T extends Versioned>(
{id, version, ...args}: T): Serialized<T> {
return {
id, version,
definition: {...args}
}
}
הנה הקישור ל-TS Playground.
