TypeScript 在4.8版本中,字符串联合类型扩大为字符串的回归问题,

u5rb5r59  于 6个月前  发布在  TypeScript
关注(0)|答案(5)|浏览(61)

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

🙂 预期行为

字符串联合类型保持为联合,而不是扩大

dpiehjr4

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"; } |

eanckbw9

eanckbw92#

4.7.2和4.8.2之间的变化发生在a2b785b

ycl3bljg

ycl3bljg3#

$12\times 3+12$ $=48$(个) 答:一共有$48$个松果.

pw9qyyiw

pw9qyyiw4#

我认为里程碑应该调整,因为那艘船已经驶过了...:)

z9smfwbn

z9smfwbn5#

谢谢。我忘了更新这个问题,但我们决定修复看起来有点冒险,在小数量的报告中,我们已经得到了这个问题。

相关问题