microsoft / microsoft/TypeScript

Multiple keys being remapped to same key causes unstable modifier propagation

Ouverte
#62,318 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Bug Domain: Mapped Types Help Wanted
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

### 🔎 Search Terms

Mapped Types, Key Remapping

### 🕗 Version & Regression Information

- This has been happening since first release of key remapping at 4.1 (tested with v4.1.5 at Playground) until nightly (tested with v6.0.0-dev.20250822 at Playground).

### ⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAShC2BDMBpCIAqB7AkgOwEtgDEAbABUQCdgAeDAPigF4oBvAKCm6gG0UoBPFADW6LADMoGKIgDOUARAAewCHgAmCgAYASNkIkQqUAGIEqc4AF8AdPsPGoAfThXr2qAH4zFq1AAuRQBdILwAV1JSAG4Oa1iOUEhfS2AAeTBiLDwyFlgEZDRMXEJiMkoaWk4eKAB6WqgAPS8uHgAiCSwsWwAjajavIKsqIQBzWJqOrt7EAC82sPD4HuNY6wYEpOhzVLgAR3CLCA08uCRUdGx8IhIKajpqnnqmlsnO7r75xeXV1u4pj79QZQYZjNYbDhAA

### 💻 Code

```ts
type RemapKeyToInitialPart = {
[K in keyof T as K extends `${infer First}.${infer _Rest}` ? First : K]: null;
};

type FirstOptional = RemapKeyToInitialPart<{
// ^?
"foo.bar"?: string;
"foo.baz": number;
}>;

type FirstRequired = RemapKeyToInitialPart<{
// ^?
"foo.baz": number;
"foo.bar"?: string;
}>;
```

### 🙁 Actual behavior

`type FirstOptional` and `type FirstRequired` results in different types:
- `type FirstOptional` has *optional* property `foo`
- `type FirstRequired` has *required* property `foo`

### 🙂 Expected behavior

`type FirstOptional` and `type FirstRequired` results in same type. I would expect it to be same as ~~`type FirstRequired`~~ `type FirstOptional`.

### Additional information about the issue

My motivation was to implement a utility `type Expand` which transforms `{ "foo.bar": number }` to `{ foo: { bar: number } }` ([playground](https://www.typescriptlang.org/play/?exactOptionalPropertyTypes=true#code/C4TwDgpgBAogHmAhgOwCYB4AqA+KBeKAbwCgoyoBtAaSgEtkoBrCEAewDMpMpEBnKAGK0ATr2AAFRMOAB5duirYAugC4oAJQhiZAIwBWEAMbAsAGkEixk6XIXZsxAL7FioSBdESps+YvxQaCDhgCDR+AAMAEkJ6dghhQUcAOmixYXoAc0dwqAB+QSg1GgAyKDTMlzdoTW19IxNMc0Dg0NR+cuQM3AJuIJCwokpxOgYqJVy1WPioADUoRzzZwtgEFAwSciGRphYOLh5+Yb7WiOiqZOiphJrgbMWb5eQIADd41S4KcSUAbicHYlQRgANlJoIZWMgxFBgABGNTwJBodAbcgAIgAFqwMhAkuwAK4ZRBJMC0NioiZQZB4gC2Oniv02GKxOPYrFYSR0UlRag6GV+jmwv1hSUx2NyuIJiHFJLYZUQwFovHYtC0lJpdISAB8oHi0BBlU9UK4YSLmbi2RypHKFUqVe1gOlOr8AcDQVBwZDgNCAEzw1ZIlFkJnY83sznCbllB2ZBlo0UsyXE0msclqKm0+l-IXe01iiWE6XJ62K5Wq9MaqDa3WAg0QI3AHPx0OWhK8eUlu1Rx184hAA))

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Reproduisez les deux exemples de types mappés à l’aide du TypeScript Playground lié et comparez FirstOptional avec FirstRequired. Étudiez le comportement du compilateur lors du remappage des clés, puis ajoutez un test de régression montrant que les deux ordres de déclaration produisent la même optionalité des propriétés ; la tâche sera considérée comme terminée lorsque le test réussira avec des résultats identiques.

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
42/100

Recevez les nouvelles issues par e-mail

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