microsoft / microsoft/TypeScript
Branded literal type widened in unexpected way
还没有人认领这个 Issue。
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
### 🔎 Search Terms
literal intersection branded string
### 🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about branded strings/literal intersections.
### ⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.7.3#code/CYUwxgNghgTiAEYD2A7AzgF3hgngBxAGkQcAueAVxQEsBHChNHAWwCMkIBuAKG9wPgAVfCACSAEQA8wgQF5KKANYokAdxQAaeBPggAHhhApgaeJhjUUAc3jzzlqwD5b28fABk8AN7wA2vyISAF0AfnIZBABfHm4AMyowDGpUbBEJaREtHX1DY1N7a0cACmpgcgkASnC0qQis8Wcvbnh4OAwKGBR4Up5I3gD4YhwAeVjpbIMjEyEa53lBCdzpiPSoFBwtS1iQGFdnENd4chQQADcdmIGI0fG3HKnTFYaXBbvJvJmCdK2dz5B9v5HeAnc4wS4ieAABRgSFOpRAaEkkN072WsxcPjgUGAqAgOD8gm6XSGN0hjiC1QIpOc0V4AHo6fAALQssAUDAspm8SyGGCxKBgBAAMSQSG8zRa8FioqKVXgpyQPW4fW4yHQWBFYvkAQkRQARJq9RUzFAkmhYtQEX90prHDwGZL4AA9EK8NWYeAAIVg5GhsPhiICSFi8FtGIlLV8mop4sdjulSFl3j6jr60SAA
### 💻 Code
```ts
declare const typeKey: unique symbol;
type TypeID = ID & { [typeKey]?: Type };
function typeID(id: ID): TypeID {
return id;
}
type KeyOf = TID extends TypeID ? ID : never;
type TypeOf = TID extends TypeID ? Type : never;
type Provides
= { readonly [T in KeyOf
]: TypeOf
};
// ---cut---
interface Foo {
foo(): void;
}
const Foo = typeID("Foo") satisfies TypeID;
// ^? const Foo: TypeID
const Bar: Provides = {
[Foo]: {
foo() {}
}
};
```
### 🙁 Actual behavior
Fails to compile with error:
```
Property 'Foo' is missing in type '{ [x: string]: { foo(): void; }; }' but required in type 'Provides>'.
```
### 🙂 Expected behavior
I'd expect it to compile. Rather than widening the literal type to `string`, I'd expect it to discard the `{ [typeKey]?: Type }` part, since that's pretty much bogus at runtime anyway.
However, it should also not lose the type information for the generic types. For instance, if I change the declaration to...
```ts
type TypeID = ID;
```
...then it does compile, but so does this...
```ts
const Bar: Provides = {
[Foo]: {
// No error about missing member `foo` here!
}
};
```
### Additional information about the issue
Possibly related to https://github.com/microsoft/TypeScript/issues/43852#issuecomment-1671115898
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 TypeScript Playground 中的复现开始,并将 branded literal 的行为与 issue #43852 中的相关讨论进行比较。跟踪针对 `TypeID`、`KeyOf`、`TypeOf` 和 `Provides` 定义的类型检查路径;完成的标准是示例能够编译,同时在适当情况下仍报告缺少 `foo` 成员。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- compilers, devtools
- Issue 类型
- 缺陷
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100