typescript - Cum pot să schimb tipul lui Object.fromEntries?


Vreau să schimb tipul obiectului creat de fromEntries pentru a fi al interfeței Program:

interface exerciseCategory {
  [exerciseCategories: string]: string[];
}

interface muscleGroup {
  [muscleGroups: string]: exerciseCategory;
}

export default interface Program {
  [days: string]: muscleGroup;
}

const program: Program = {
  "Day 1": {
    Chest: {
      warmUp: ["parallel bar dips"],
      main: ["Bench Press", "Inclined Bench press", "Decline Bench press"],
      secondary: ["Dumbbell Flys", "Cable Crossover Flys", "Pec-deck Fly"],
    },
    Biceps: {
      Lola: ["Barbell Curl", "Preacher Curl"],
      bobo: ["Hammer Curls", "Cable Curl", "Dumbbell Curl"],
    },
  },
  "Day 2": {
    Shoulders: {
      coso: ["parallel bar dips"],
      coque: ["Bench Press", "Inclined Bench press", "Decline Bench press"],
      sdary: ["Dumbbell Flys", "Cable Crossover Flys", "Pec-deck Fly"],
    },
    Abs: {
      main: ["Crunch", "Leg raises"],
    },
  },
  "Day 3": {
    Back: {
      warmUp: ["parallel bar dips"],
      main: ["Bench Press", "Inclined Bench press", "Decline Bench press"],
      secondary: ["Dumbbell Flys", "Cable Crossover Flys", "Pec-deck Fly"],
    },
    Triceps: {
      main: ["Barbell Curl", "Preacher Curl"],
      secondary: ["Hammer Curls", "Cable Curl", "Dumbbell Curl"],
    },
  },
};



const days: Array<[string, object]> = Object.entries(program);

days[0][0] = 'New day name'

const newProgram:Program = Object.fromEntries(days)

Totuși, pentru const newProgram:Program=Object.fromEntries(days) primesc: Tipul '{ [k: string]: object; }' nu poate fi atribuit tipului 'Program'. Semnăturile de index sunt incompatibile. Tipul 'object' nu poate fi atribuit tipului 'muscleGroup'. Semnătura de index lipsește în tipul '{}'

Cum pot să îl fac să funcționeze?

Teren de joacă

Răspuns #1

Adesea, în TypeScript, un parcurs dus-întors prin Object.entries() și Object.fromEntries() va pierde informații despre relațiile dintre anumite chei și tipurile valorilor lor, și va trebui să folosești o aserțiune de tip undeva pentru a păstra sau a re-stabili astfel de informații.

În cazul tău, însă, Program nu are chei cunoscute în mod special; are o semnătură de index de tip string, astfel încât fiecare cheie posibilă de tip string poate avea o valoare de tip muscleGroup. Prin urmare, Object.entries() și Object.fromEntries() vor funcționa fără probleme așa cum sunt, decât dacă te pui în calea lor.

Dintr-un anumit motiv, ai adnotat days ca fiind de tip Array<[string, object]>, extinzând tipurile valorilor de la muscleGroup la object. Aceasta elimină informația. Ar fi mai bine să lași compilatorul să infereseze tipul lui days:

const days = Object.entries(program);
//  [string, muscleGroup][]

Și atunci totul va funcționa așa cum era de așteptat:

const newProgram: Program = Object.fromEntries(days); // okay

Link de teren de joacă către cod

Răspunsul #2

în unele dintre cele mai multe cazuri poți elimina tipurile și lăsa TypeScript să le deducă. În cazul tău poți elimina tipul pentru days - Array<[string, object]>. TS le va deduce din declarațiile de tip pentru program și Object.entries.

const days = Object.entries(program);

days[0][0] = 'New day name'

const newProgram:Program = Object.fromEntries(days)

Aici ai cod funcțional în playground