microsoft / microsoft/TypeScript

Inside a generic function with a remapped type as parameter, elements are wrongfully inferred as {}.

未关闭
#63,363 4 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Needs Investigation
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

### 🔎 Search Terms

remapped
key mapping
generics

Maybe related:
- https://github.com/microsoft/TypeScript/issues/47794
- https://github.com/microsoft/TypeScript/issues/48855

### 🕗 Version & Regression Information

- tested on playground v6.0.2

### ⏯ Playground Link

[Playground Link](https://www.typescriptlang.org/play/?declaration=false#code/PTAEBUFMGcBdoFAJKAQgVQOIEYkG9QUBtAaVAEsA7UOAJyoHMAyAa0gE8B7AM1AAlQAQ2igABp0oASPAGFBAB3KxBAG3IAvSAB4SAPgC+ogLoACgLy6I7eZFAByPPruh5tTgDdyAExihKnUABbQVgAYwALUG5OWlBYcNtocgZKEIBXWlsAOgRQPLjrWwAlSFTAyBIOaC0BSAAPWFKvERLQmK8tOkYAGiFKdl1LM1A8XPzx0gpqLspmNi5eAWExCWk5RWU1TR0DYwAuUAAKAEpQC1B3Tm8xvP0AbiRx7jTKUNhyCSjOTi1wUHrGpRmqBWu1OrB6LNeoJ+oNDuEYV4VJBaNADiUyhUqr9dKdRjdxl9aIc2pQ4H5BOUpqAEUDkai8QTCflkbAaYj6QcTmdLJdvGd2XSUdAiJijABCO6EMD+FiPZmEzKwDLUWlI4WiymQCUPBWgfTy5nxNwAdz8kDNAFFaG5iQAiTgsO3HXX5A0E0nkuoC6KcQ54CQAMW+XNO50c+hd0qOYd5Vy8DwNBGIZCoNAhjFYHB4-FM50dOXGsEKINKWsq7GqtQaTRakDatA6MwY0NhQxGTPykzTzazC1zoZ5F3jBPuhqiLzeH2ovt+-xrQLrDabGahfQGunhHOF6LL5Qr1XAuI7nby0WJnrZmOpavp0EZevGrMF6tog-OfK8AtvGrFkujjrjnqSoqi+d6auUOqnvqQH5ManBmpQFqgNatqHA6TouqO46XqA3rDL6-pBiGMZDhGUYoNyH7xomSAoBgmAAEz4NG3bTKuczZoseaWIcWT8YItAMGioAvCw-gmpQsbDtcRYlhi5bYtWgLAqCjbgpCLbrkQRiDAKox6mx6aaX2OZ8EYXL8VkgnCQcfCkEY0mfqODwEs8rzvJ8s5-ACtalsuGk9OucI-qiu6YgeOKMtB54khI5LXmmoX3h2j75CgJppLAAD8uXQU+kBsqF75xvywzJRB2qSrBzIgbQqrbqilVQXq7p6vBiHIahMToY6zqurcOHxWy+FfH6AaUMGnBcpABwACxzdJ5FSigsoIEmrGptQ8xmTxoAFgSxY2KWEVKfOKlLmCzatuwOl6cMBkKkZO3cZZAlCSJ9kkI5Q7OeMY5uZOnkzt8c6+Yu-lXRxN0hY1IkKfu2JHtFeqxbhiUNUKDKpWloDPsVpHUWVYG-lqOoAXK+X5HVmOviKf4DYSbUKh15pWjaPUYf12EesNeE+t8RGTSRhyzaAADMjFLfokYrcAgH6EAA)

### 💻 Code

```ts
type RenameKeys> = {
[K in string&keyof H as `on${Capitalize}`]: () => void
};

function foo>(handlers: RenameKeys) {

for(const name in handlers) {
let handler: () => void = handlers[name]!; // nok
// inferred as {} instead of () => void;
// Type 'NonNullable[Extract, string>]>' is not assignable to type '() => void'.
// Type '{}' provides no match for the signature '(): void'.(2322)
}
}
```

### 🙁 Actual behavior

The type of the elements of the remapped type is `{}` inside the generic function.

If we return the element, the returned type is correct (cf playground).

### 🙂 Expected behavior

The type should be either:
- `() = void` (correct)
- `unknown` or `any`: TS is unable to properly infer the type.

Having `{}` is quite strange/surprising.

### Additional information about the issue

There is another issue with `[K in string&keyof H]` which doesn't manifest when we use `[K in keyof H]` (cf playground):

```ts
type RenameKeys> = {
[K in string&keyof H]: (...args: H[K]) => void
};

function foo>(handlers: RenameKeys) {

for(const name in handlers)
return handlers[name]!;

throw new Error("ok");
}

const x = foo({onFoo: (e: 42) => {}}); // nok : (...args: unknown) => void
```

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从链接的 Playground 复现开始,将使用 `string & keyof H` 的重映射类型与 `keyof H` 变体进行比较。跟踪元素访问在泛型函数 `foo` 中是如何被推断的。完成标准是:重映射后的 handler 元素被推断为 `() => void`,或被推断为 `unknown` 或 `any` 而不是 `{}`,并覆盖报告中的案例。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
compilers
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。