Microsoft/TypeScript

Multiple keys being remapped to same key causes unstable modifier propagation

Open

#62.318 geöffnet am 22. Aug. 2025

Auf GitHub ansehen
 (3 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)TypeScript (6.726 Forks)batch import
BugDomain: Mapped TypesHelp Wanted

Repository-Metriken

Stars
 (48.455 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 6T 17h) (9 gemergte PRs in 30 T)

Beschreibung

🔎 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

type RemapKeyToInitialPart<T> = {
    [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<T> which transforms { "foo.bar": number } to { foo: { bar: number } } (playground)

Contributor Guide