Типскрипт - объект с динамическими c и предопределенными ключами, но с разными типами в качестве значений (или: объект с определением для «остальных ключей») - PullRequest
0 голосов
/ 07 августа 2020

Я конвертирую проект из 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",
    }
  }
}

Но это очень много преобразования в делаю в моем проекте, и мне тоже хочется сдаться ...

1 Ответ

1 голос
/ 07 августа 2020

Это происходит потому, что TOTAL также соответствует определению [key: string]: type_B, но это решение должно работать для вас

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...