Bug报告
🔎 搜索词
string union widening
, string union regression
, union widening
🕗 版本与回归信息
此回归发生在4.8.0版本中,可以在TS Playground中使用4.8.0-beta
和nightly(4.9.0-dev.20220904
)标签重现。这也可以在4.7.4
中使用。
- 在4.7.4和4.8.0-beta版本之间发生了变化
我觉得这可能与改进的绑定模式推断有关。
⏯ Playground链接
带有相关代码的Playground链接
要重现,将鼠标悬停在"isWorking"变量上,可以看到类型定义包括字符串的联合。切换到4.8.0-beta版本,并注意类型定义现在只是string
。
💻 代码
interface Guard<T> {
(val: unknown): val is T;
}
type ObjectGuard<T> = {
[key in keyof T]: Guard<T[key]>;
};
function isObject(val: unknown): val is Record<string, unknown> {
return val !== undefined && val !== null && typeof val === 'object' && !Array.isArray(val);
}
function isObjectOfShape<T>(
value: unknown,
shape: ObjectGuard<T>,
): value is T {
if (!isObject(value)) {
return false;
}
let validShape = true;
for (const key in shape) {
const guard = shape[key];
if (guard && !guard(value[key])) {
return false;
}
}
return validShape;
}
function createObjectGuard<T>(guard: ObjectGuard<T>) {
return (val: unknown): val is T => isObjectOfShape(val, guard);
}
function asLiteral<T extends (string | boolean | number)[]>(...literals: T) {
return (val: unknown): val is T[number] => {
return literals.includes(val as T[number]);
};
}
// See type of `isWorking` - should include the type key as a union of strings
const isWorking = createObjectGuard({
// ^?
type: asLiteral('these', 'should', 'be', 'a', 'union'),
});
🙁 实际行为
字符串联合类型被扩大为string
。
🙂 预期行为
字符串联合类型保持为联合,而不是扩大
5条答案
按热度按时间dpiehjr41#
你好,我是Repro bot。我可以协助缩小范围并跟踪编译器错误!此评论反映了问题正文中运行的夜间TypeScript版本中的重现状态。
问题正文代码块由@me4502提供
⚠️Assert:
const isWorking: (val: unknown) => val is { type: string; }
历史信息
| 版本 | 重现输出 |
| ------------ | ------------ |
| 4.8.2 | ⚠️ Assert:*
const isWorking: (val: unknown) => val is { type: string; }
|| 4.4.2, 4.5.2, 4.6.2, 4.7.2 | ⚠️ Assert:*
const isWorking: (val: unknown) => val is { type: "these" | "should" | "be" | "a" | "union"; }
|eanckbw92#
4.7.2和4.8.2之间的变化发生在a2b785b。
ycl3bljg3#
$12\times 3+12$ $=48$(个) 答:一共有$48$个松果.
pw9qyyiw4#
我认为里程碑应该调整,因为那艘船已经驶过了...:)
z9smfwbn5#
谢谢。我忘了更新这个问题,但我们决定修复看起来有点冒险,在小数量的报告中,我们已经得到了这个问题。