我有以下类型的update msg model =
case msg of
UrlRequested (Browser.Internal _) ->
( model, Cmd.none )
UrlRequested (Browser.External "") ->
( model, Cmd.none )
UrlRequested (Browser.External url) ->
( model, Browser.Navigation.load url )
UrlChanged _ ->
( model, Cmd.none )
:
User
因此,从本质上讲,用户可以是具有名称和电子邮件属性的对象,也可以是空对象。
当我尝试检查给定用户对象的两个中的 时,TypeScript显示错误。
type User = {
name: string;
email: string;
} | {};
具体来说,以上代码会引发错误:
if (user.name) { // ERROR
// do something if user object is populated
}
是否有可能存在一个区分联合,其中接口之一是空对象?
答案 0 :(得分:1)
有区别的联合(在TypeScript中通常理解为该术语)是这样一种联合,其中在联合的每个成员上都有一个具有不同值的 discriminant 属性。因此,根据定义,包含{}
的联合不是歧视性联合。如果您愿意将设计更改为使用有区别的联合,那么一切都会正常。
当前的设计:通常,TypeScript对象类型包括具有至少个指定属性的任何对象。这意味着{}
实际上是任何对象的类型,而您的User
的类型只是简化为{}
。没有(合理的)方式来表达没有属性的对象的类型。 this suggestion可能要加一个。您必须先投射对象,然后才能测试name
属性,即使您测试了该属性,我也不知道有什么方法可以使TypeScript自动知道email
属性存在。您至少可以定义一个user-defined type guard以将所有混乱隐藏在一个函数中。
答案 1 :(得分:1)
您可以in
https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-the-in-operator
if (user.name) { // error
user // typeof user is User | {}
user.name // error
user.email // error
}
if ('name' in user) {
user // ok, typeof user is User
user.name // string
user.email // string
}