2 votes

La propriété n'existe pas sur le type d'interface de l'union

J'ai un objet qui contient un tableau de membres de l'équipe, le plus petit type d'objet implémente soit interface Member o interface Manager . Les objets-gestionnaires peuvent contenir d'autres objets interface Member objets. Chaque membre/gestionnaire a son propre key: string .

Comme vous pouvez le voir dans le code, j'essaie de mettre en œuvre une fonction setProfession(key, profession) qui fixe un profession: string pour un membre ou un gestionnaire donné, en fonction de ses besoins personnels. key: string .

Il y a cette erreur dans mon setProfession fonction :

Property 'members' does not exist on type 'Member | Manager'.

Je ne comprends pas l'erreur, parce que j'ai mis un garde-fou sur la ligne juste avant la ligne où se trouve l'erreur. Pourtant, il y a toujours une erreur, même si interface Manager contient évidemment le members propriété : Écran d'impression d'erreur

interface Member {
  key: string;
  name: string;
  profession: string;
}

interface Manager {
  key: string;
  name: string;
  profession: string;
  members: Array<Member>
}

interface Team {
  members: Array<Member | Manager>
}

const TEAM: Team = {
  members: [
    {
      key: 'RodneyMcKay1',
      name: 'Rodney McKay',
      profession: 'Scientist'
    }, {
      key: 'JohnShephard1',
      name: 'John Shephard',
      profession: 'Soldier',
      members: [
        {
          key: 'TeylaEmmagan1',
          name: 'Teyla Emmagan',
          profession: 'Soldier'
        }, {
          key: 'RononDex1',
          name: 'Ronon Dex',
          profession: 'Soldier'
        }
      ]
    }
  ]
};

const isManager = (member: Member | Manager): member is Manager => {
  return member.hasOwnProperty('members');
}

const setProfession = (key: string, profession: string): boolean => {
  for (let i = 0; i < TEAM.members.length; i++) {
    if (isManager(TEAM.members[i])) {    // SAFE GUARD 
      for (let j = 0; j < TEAM.members[i].members.length; j++) {    // ERROR
         if (TEAM.members[i].members[j].key === key) {    // ERROR
           TEAM.members[i].members[j].profession = profession;    // ERROR
           return true;
         }
      }
    } else if (TEAM.members[i].key === key) {
      TEAM.members[i].profession = profession;
      return true;
    }
  }

  return false;
}

2voto

Alex Wayne Points 58113

Typescript n'est pas en mesure de suivre toutes les entrées. Vous pouvez l'aider en affectant la valeur testée à une variable :

  for (let i = 0; i < TEAM.members.length; i++) {
    const person = TEAM.members[i]

    if (isManager(person)) {
      for (let j = 0; j < person.members.length; j++) {
         if (person.members[j].key === key) {
           person.members[j].profession = profession;
           return true;
         }
      }
    } else if (person.key === key) {
      person.profession = profession;
      return true;
    }
  }

Voir l'aire de jeux


Cela devient beaucoup plus facile si vous utilisez l'itération au lieu de boucles indexées. Dans ce cas, cette variable est créée gratuitement dans le cadre de cette boucle. Et votre code est plus facile à lire et à comprendre, ce qui est un avantage supplémentaire.

  for (const person of TEAM.members) {
    if (isManager(person)) {
      for (const member of person.members) {
         if (member.key === key) {
           member.profession = profession;
           return true;
         }
      }
    } else if (person.key === key) {
      person.profession = profession;
      return true;
    }
  }

Voir l'aire de jeux

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X