假设我有输入:
type UnionType = 'cat' | 'dog' | 'bird';
type MappedType = {
[Key in UnionType]: UnionType;
};
但这只能给出:
type MappedType = {
'cat': UnionType;
'dog': UnionType;
'bird': UnionType;
}
我想要实现的是:
type MappedType = {
'cat': 'cat' | 'dog' | 'bird';
'dog': 'cat' | 'dog' | 'bird';
'bird': 'cat' | 'dog' | 'bird';
}
也就是说,不透露类型名称
UnionType
。这可能吗?
您拥有的类型与您想要的类型相同。您主要关心的是类型如何“显示”,但开发人员没有可靠的记录方法来控制它。从本质上讲,编译器有权选择如何显示这些内容,并且它使用启发式方法来确定何时按原样保留命名类型以及何时用其定义替换名称。 microsoft/TypeScript#45954 有一个功能请求,为开发人员提供更多控制权,还有 microsoft/TypeScript#28508 允许“可扩展”定义。但就目前而言,这有点超出我们的掌控范围。 当然有一些方法可以利用编译器的启发式规则来尝试更改显示的类型。您可以在这里做的一件事是与空类型
UnionType
{}
。空类型匹配除 null
和 undefined
之外的任何内容,因此 UnionType & {}
完全等同于 UnionType
。但 TypeScript 不想按原样显示 UnionType & {}
;它试图进一步评估它:type MappedType = { [K in UnionType]: UnionType & {} };
/* type MappedType = {
cat: "cat" | "dog" | "bird";
dog: "cat" | "dog" | "bird";
bird: "cat" | "dog" | "bird";
} */
这样就可以得到你想要的行为。对于这个特定用例,适用于 TypeScript 5.4。但同样,这里也没有任何保证。也许 TypeScript 的某些未来版本会改变其显示方式。尝试了解为什么
您关心显示两种等效类型中的哪一种,以及是否有其他不依赖于它的方法(例如,更多代码文档)可能是值得的。
Playground 代码链接