2
votes

rxjs attend le type d'union lors du mappage interne switchMap

Démo ici

switchMap(innerHello => {
    return of(world).pipe(map(innerWorld => [innerHello, innerWorld]));
}),
map(([hello, world]) => {
  console.log('result', hello.hello, world.world);
})

Comment se fait-il que, lors de l'utilisation de l'opérateur switchMap , j'ai un avertissement disant que la propriété hello n'existe pas sur le type Hello | Monde .
Je renvoie un tableau à partir de la carte intérieure, alors pourquoi attend-il une union?


3 commentaires

Cela semble fonctionner dans le lien de démonstration que vous avez partagé


Oui cela fonctionne mais j'ai des avertissements (les lignes rouges ondulées) sur bonjour et monde.


Vous devez spécifier les types d'arguments: map (([hello, world]: [Hello, World])


3 Réponses :


-1
votes

Je renvoie un tableau à partir de la carte intérieure, alors pourquoi attend-il une union?

C'est ce à quoi vous lui avez explicitement dit de s'attendre:

  console.log('result', hello.hello, world.world);

Alors, "accédez à la propriété hello du code hello > objet (ou: 0e élément du tableau), et accédez à la propriété world de l'objet world ".

Remplacez-le par console.log ('result', bonjour, monde) .


3 commentaires

Que voulez-vous dire? Les avertissements me disent que bonjour pourrait être de type Hello ou World, mais je n'ai jamais dit cela explicitement.


Il déduit les types, à partir du type de innerHello et du type de world (celui du return of (world) ) est.


C'est vrai, j'ai (à tort) pensé que [Hello, World] serait déduit comme tel. Pas [Hello | World].



5
votes

Le type inféré de [innerHello, innerWorld] est Array vous ne pouvez pas accéder aux propriétés qui ne sont pas dans les deux types.

Ce que vous pouvez faire est de taper explicitement votre tableau comme

map(([hello, world]: [Hello, World]) => {
  console.log('result', hello.hello, world.world);
})


1 commentaires

Merci, comme je le disais dans un autre commentaire, j'ai pensé que [Hello, World] serait déduit comme tel, pas comme [Hello | World]. Je vous remercie.



2
votes

Comme déjà mentionné dans une autre réponse, dactylographié déduit le type des objets dans le tableau comme le type d'union Monde | Bonjour , vous ne pourrez donc pas accéder aux propriétés non courantes entre les classes sans utiliser une forme de type guard .

La réponse fournie par @David est bonne, mais elle vous oblige à convertir le type du tableau strong >.

Notez que cela ne fonctionnera pas sans avertissement du compilateur dans le cas où vous changez l'ordre dans lequel vous ajoutez les objets dans le tableau lors de sa création. (Par exemple: [innerHello, innerWorld] dans [innerWorld, innerHello] ).

Une autre façon d'aborder cela, en gardant les vérifications de type sans le casting de type et, par conséquent, un meilleur support du compilateur, consiste à collecter les propriétés dans un objet simple, puis à le déstructurer:

const helloVal: Hello = {
  hello: 'hello'
};
const worldVal: World = {
  world: 'world'
};

const source = of(helloVal).pipe(
  switchMap(hello => of(worldVal).pipe(map(world => ({ hello, world }))))
);

source.subscribe(({ hello, world }) => {
  console.log('result', hello.hello, world.world);
});

Dans ce cas, les types de hello code> et world sont correctement déduits dans le rappel subscribe . Notez que dans ce cas, vous êtes "lié" aux noms des propriétés utilisées pour créer l'objet de résultat, pas à leur ordre .

Démonstration de travail dans ce blitz


0 commentaires