microsoft / microsoft/TypeScript

Discriminated union narrowing fails when use template literal types as tag

Ouverte
#42,007 3 commentaires 3 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Awaiting More Feedback Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

TypeScript Version: 4.2.0-dev.20201211

Search Terms: narrowing, discriminated union, template literal types

Code

type Types<T extends string> = {
  one: `${T}/one`;
  two: `${T}/two`;
}
type OneObj<T extends string> = {
  type: Types<T>["one"];
  one: string;
}
type TwoObj<T extends string> = {
  type: Types<T>["two"];
  two: string;
}
type OneOrTwoObj<T extends string> = OneObj<T> | TwoObj<T>

declare function acceptsOneObj<T extends string>(oneObj: OneObj<T>): void;
declare function acceptsTwoObj<T extends string>(twoObj: TwoObj<T>): void;

function f<T extends string>(oneOrTwoObj: OneOrTwoObj<T>, types: Types<T>){
  switch(oneOrTwoObj.type){
    case types.one:
     return acceptsOneObj(oneOrTwoObj); // Error: Argument of type 'OneOrTwoObj<T>' is not assignable to parameter of type 'OneObj<T>'.
    case types.two:
     return acceptsTwoObj(oneOrTwoObj); // Error: Argument of type 'OneOrTwoObj<T>' is not assignable to parameter of type 'OneObj<T>'.
  }
}

Expected behavior:
oneOrTwoObj should be narrowed to OneObj or TwoObj in function f

Actual behavior:
narrowing fails

Playground Link:
playground

Related Issues:

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par la reproduction liée dans TypeScript Playground et la fonction générique f, en vous concentrant sur la manière dont le switch sur oneOrTwoObj.type gère les types de littéraux de modèle. Confirmez le comportement actuel, puis retracez le chemin de vérification des types pour le narrowing des unions discriminées. C’est terminé lorsque chaque branche du switch restreint oneOrTwoObj au OneObj ou TwoObj correspondant, de sorte que les appels à acceptsOneObj et acceptsTwoObj passent la vérification des types.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.