microsoft / microsoft/TypeScript
{} and { [K in never]: any } exhibit different simplification behavior
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 1 j 19 h
- PR mergées (30 j)
- 117
Description
Bug Report
Under some circumstances, TypeScript treats { [K in never]: any } & { foo?: number } differently than {} & { foo?: number }. However, this does not occur with { [K in never]: any } & { foo: number }.
🔎 Search Terms
empty mapped object type, intersection with optional object, K in never
🕗 Version & Regression Information
Tested on 4.0.5, 4.1.5, 4.2.0-beta, and the current nightly
⏯ Playground Link
💻 Code
type AreAllStringsTs<T> = string extends T ? true : false;
type Test1 = AreAllStringsTs<{ foo?: number }>; // expected: false, actual: false
type Test2 = AreAllStringsTs<{ foo: number }>; // expected: false, actual: false
type Test3 = AreAllStringsTs<string | number>; // expected: true, actual: true
type Test4 = AreAllStringsTs<{ [K in never]: any } & { foo?: number }>; // expected: false, actual: true <-- FAIL
type Test5 = AreAllStringsTs<{ [K in never]: any } & { foo: number }>; // expected: false, actual: false
🙁 Actual behavior
Test4 is true.
🙂 Expected behavior
Test4 is false.
Potential Workaround
If you have a mapped object type in which the type expression for the keys might reduce to never, add a conditional check to see if the keys set is empty. For example, I encountered this when working with a type that would make all keys of an object that could take on the value undefined optional:
type Optionalize<T> =
{ [K in RequiredKeys<T>]: T[K] }
& { [K in NonRequiredKeys<T>]?: T[K] };
Adding a check for never made the behavior consistent with what I was expecting when every field of the input type accepted undefined:
type Optionalize<T> =
(RequiredKeys<T> extends never ? {} : { [K in RequiredKeys<T>]: T[K] })
& { [K in NonRequiredKeys<T>]?: T[K]; };
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par le lien Playground fourni et reproduisez la différence entre Test4 et Test5. Suivez la manière dont le compilateur simplifie le type mappé vide lorsqu’il est intersecté avec des types d’objet optionnels et requis. C’est terminé lorsque Test4 est évalué à false, tandis que les autres attentes signalées restent inchangées.
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