TypeScript-type-guard不';t意识到字符串并集已减少

TypeScript-type-guard不';t意识到字符串并集已减少,typescript,Typescript,在下面的代码中,我希望TypeScript能够意识到,在注释行中,用户对象对于角色不能有任何其他值,对于管理员除外 确实如此!如果您将此代码粘贴到TypeScript Played中,您会注意到,将鼠标悬停在role上,此时确实只显示admin 但是,在return DemoForAdmin行中仍然会显示一个错误。将鼠标悬停在那里的user上,显示类型的弹出窗口显示角色字段的完整联合 function Demo(user: { name: string; role: 'user' | 'admi

在下面的代码中,我希望TypeScript能够意识到,在注释行中,
用户
对象对于
角色
不能有任何其他值,对于
管理员
除外

确实如此!如果您将此代码粘贴到TypeScript Played中,您会注意到,将鼠标悬停在
role
上,此时确实只显示
admin

但是,在
return DemoForAdmin
行中仍然会显示一个错误。将鼠标悬停在那里的
user
上,显示类型的弹出窗口显示
角色
字段的完整联合

function Demo(user: { name: string; role: 'user' | 'admin'; } | null) {
    if (user === null) {
        return 'You have to be logged in.';
    }

    if (user.role !== 'admin') {
        return 'You have to be an admin';
    }

    user.role; // Hover over role to see "admin"
    return DemoForAdmin(user);
}

function DemoForAdmin(user: { name: string; role: 'admin'; }) {
    return 'You are an admin';
}

TypeScript不应该意识到将对象传递给该方法是安全的(是吗?),并且应该能够在悬停在
user
role
,而不仅仅是
role

上的两种情况下推断正确的缩小字符串并集吗,类型保护不会影响包含的对象类型

还有另一种结构允许您执行此操作,称为歧视联合。类型必须是对象类型与文字类型的鉴别器的并集。在这种情况下,可以使用
角色
。这应该行得通

function Demo(user: { name: string; role: 'user' } | { name: string; role: 'admin'; } | null) {
    if (user === null) {
        return 'You have to be logged in.';
    }

    if (user.role !== 'admin') {
        return 'You have to be an admin';
    }

    user.role; // Hover over role to see "admin"
    return DemoForAdmin(user);
}

function DemoForAdmin(user: { name: string; role: 'admin'; }) {
    return 'You are an admin';
}
你可以阅读更多关于歧视工会的内容