microsoft / microsoft/TypeScript

Regression: Mapped types are no longer homomorphic when wrapped in certain conditional types

Open
#63,132 2 comments 0 reactions 1 assignee View on GitHub

@ahejlsberg is already working on this.

Since Feb 13, 2026.

Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

### 🔎 Search Terms

"homomorphic" "keyof" "extends"

### 🕗 Version & Regression Information

- This changed between versions 3.8.3 and 3.9.7

### ⏯ Playground Link

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

### 💻 Code

```ts
type KeyMap = keyof T extends PropertyKey ? { [K in keyof T]: K } : never;

type X = KeyMap;
```

### 🙁 Actual behavior

`X` is evaluated to

```ts
type X = {
toString: "toString";
toFixed: "toFixed";
toExponential: "toExponential";
toPrecision: "toPrecision";
valueOf: "valueOf";
toLocaleString: "toLocaleString";
}
```

### 🙂 Expected behavior

`X` should be evaluated to `number` because according to [the FAQ](https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs),

> Mapped types declared as `{ [ K in keyof T ]: U }` where T is a type parameter are known as `homomorphic mapped types`, which means that the mapped type is a structure preserving function of `T`. When type parameter `T` is instantiated with a primitive type the mapped type evaluates to the same primitive.

### Additional information about the issue

Replacing `PropertyKey` with either `unknown` or `any` fixes the issue for some reason.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.