【问题标题】:TypeScript type guard doesn't realize string union has been reducedTypeScript 类型保护没有实现字符串联合已减少
【发布时间】:2019-04-25 18:35:25
【问题描述】:

在下面的代码中,我希望 TypeScript 应该能够意识到,在注释行中,user 对象不能有任何其他值 role 期望 admin

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

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

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 不应该能够意识到将对象传递给该方法是安全的(是吗?还有role,不只是role

【问题讨论】:

    标签: typescript


    【解决方案1】:

    类型保护只适用于字段并且只缩小字段,类型保护不会影响包含对象的类型。

    还有另一种结构允许您执行此操作,称为区分联合。该类型必须是具有字面量类型区分的对象类型的联合。在这种情况下,可以使用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';
    }
    

    您可以阅读有关受歧视工会的更多信息here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-27
      • 2019-02-13
      • 2017-05-18
      • 2018-12-03
      • 2019-02-04
      • 1970-01-01
      • 2023-02-15
      • 2020-01-14
      相关资源
      最近更新 更多