在下面的代码中,我希望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不能意识到将对象传递给该方法是安全的(是吗?),并且在两种情况下都应该能够推断出正确的窄字符串并集{{1} }以及user
,而不仅仅是role
?
答案 0 :(得分:2)
类型保护仅适用于该字段,并且仅缩小该字段的范围,类型保护不会影响包含的对象类型。
还有另一种允许您执行此操作的结构,称为区分联合。该类型必须是对象类型的并集,并且要具有直角形类型的判别式。在这种情况下,可以使用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