Я конвертирую проект из JS в TS и немного застрял на следующем объекте:
let campaigns = {
TOTAL: {
cost: 3,
revenue: 6,
year: 2020,
},
campaignId_1: {
name: "campaignName1",
cost: 1,
revenue: 4,
video: "video1",
},
campaignId_2: {
name: "campaignName2",
cast: 2,
revenue: 2,
video: "video2",
}
}
В Typescript я хочу, чтобы объект ВСЕГДА имел ключ «TOTAL» с значение типа A, а остальные ключи - это динамические c и должны иметь значение типа B.
Итак, сначала я определил дочерние типы:
type type_A = {
cost: number,
revenue: number,
year: number,
}
type type_B = {
name: string,
cast: number,
revenue: number,
video: string,
}
И теперь я пытаюсь создать тип для родительского объекта Campaigns:
Попробуйте 1:
type ICampaigns = {
TOTAL: type_A,
[key: string]: type_B, // Hoping it will be handled as "default" or "for all other non-defined keys"
}
Но получил следующее сообщение об ошибке: Property 'TOTAL' of type 'type_A' is not assignable to string index type 'type_B'.(2411)
.
Попробуйте 2:
type ICampaigns = {
TOTAL: type_A,
} & {
[key: string]: type_B, // Hoping it will be handled as "default" or "for all other non-defined keys"
}
И теперь он компилируется, но при попытке определить такой экземпляр я получаю ошибки независимо от того, имеет ли TOTAL тип_A или тип_B.
let campaigns: ICampaigns = {
TOTAL: {
cost: 3,
revenue: 6,
year: 2020,
},
campaignId_1: {
name: "campaignName1",
cost: 1,
revenue: 4,
video: "video1",
},
campaignId_2: {
name: "campaignName2",
cost: 2,
revenue: 2,
video: "video2",
}
}
I знаю, что выполнение type_A|type_B
решит мою проблему, но тогда ключ TOTAL сможет иметь объект type_B в качестве значения, а другие ключи Dynami c могут иметь значения type_A, что не очень хорошо.
Я также знаю, что могу преобразовать объект Campaigns, чтобы в нем были только определенные ключи:
let campaigns: ICampaigns = {
TOTAL: {
cost: 3,
revenue: 6,
year: 2020,
},
campaignDetails: { // <--- change
campaignId_1: {
name: "campaignName1",
cost: 1,
revenue: 4,
video: "video1",
},
campaignId_2: {
name: "campaignName2",
cost: 2,
revenue: 2,
video: "video2",
}
}
}
Но это очень много преобразования в делаю в моем проекте, и мне тоже хочется сдаться ...