类型注释和可区分的字符串文字联合
Type annotations and discriminated union's of string literals
我在创建符合类型注释(下面示例中的Cards
)的对象时遇到了这个问题,属性 是一种可区分的联合类型字符串文字(下例中的 CardType
),这些字符串文字与原始类型注释上的字符串文字完全相同。
// ------------ SETUP ------------
interface AboutCard {
type: 'About'
}
interface SplashCard {
type: 'Splash'
}
export type Cards = AboutCard | SplashCard
export type CardType = 'About' | 'Splash'
const type = 'About' as CardType
// ------------ SETUP END ------------
const example1: Cards = {
type
}
// ^
// Type 'CardType' is not assignable to type '"Splash"'.
// Type '"About"' is not assignable to type '"Splash"'.ts(2322)
const example2 = {
type
} as Cards
// ^ all good, no error.
const example3 = {
type: 'NOT_REAL_CARD'
} as Cards
// ^
// Types of property 'type' are incompatible.
// Type '"NOT_REAL_CARD"' is not comparable to type '"Splash"'.ts(2352)
所以基本上我想知道为什么第一个例子:
const example1: Cards = {
type
}
失败了,但最后两个例子符合我的预期。
example1
似乎符合类型 Cards
,如果您尝试将 type
显式设置为字符串文字 About
或 Splash
它工作正常,只是当它可能是受歧视的工会时,它才有问题。
对不起,我不知道怎么问才好!
我觉得可能是这样的: 提供了一些关于为什么会发生这种情况的线索?
除了没有其他属性的微不足道的情况外,{ type: 'About' | 'Splash' }
与 { type: 'About' } | { type: 'Splash' }
不同。由于您的变量 type
是所有可能判别式的并集,因此您正试图做到这一点,将一个键为 type
的对象分配给一个被判别联合 属性 的对象预计。
后两个示例之所以有效,是因为您几乎可以使用类型断言做任何事情。您实际上是在告诉编译器抑制它认为存在的类型错误。
要了解为什么这些类型不兼容,请考虑以下示例:
interface AboutCard {
type: 'About'
aboutMessage: string
}
interface SplashCard {
type: 'Splash'
spashMessage: string
}
export type Cards = AboutCard | SplashCard
export type CardType = Cards['type'] // no need to repeat string liteal types
const type = 'About' as CardType
// What properties should be required for `example1` ?
// since it is both types at the same time best case scenario would be to require all properties in teh union
const example1: Cards = {
type,
spashMessage: ""
}
我在创建符合类型注释(下面示例中的Cards
)的对象时遇到了这个问题,属性 是一种可区分的联合类型字符串文字(下例中的 CardType
),这些字符串文字与原始类型注释上的字符串文字完全相同。
// ------------ SETUP ------------
interface AboutCard {
type: 'About'
}
interface SplashCard {
type: 'Splash'
}
export type Cards = AboutCard | SplashCard
export type CardType = 'About' | 'Splash'
const type = 'About' as CardType
// ------------ SETUP END ------------
const example1: Cards = {
type
}
// ^
// Type 'CardType' is not assignable to type '"Splash"'.
// Type '"About"' is not assignable to type '"Splash"'.ts(2322)
const example2 = {
type
} as Cards
// ^ all good, no error.
const example3 = {
type: 'NOT_REAL_CARD'
} as Cards
// ^
// Types of property 'type' are incompatible.
// Type '"NOT_REAL_CARD"' is not comparable to type '"Splash"'.ts(2352)
所以基本上我想知道为什么第一个例子:
const example1: Cards = {
type
}
失败了,但最后两个例子符合我的预期。
example1
似乎符合类型 Cards
,如果您尝试将 type
显式设置为字符串文字 About
或 Splash
它工作正常,只是当它可能是受歧视的工会时,它才有问题。
对不起,我不知道怎么问才好!
我觉得可能是这样的:
除了没有其他属性的微不足道的情况外,{ type: 'About' | 'Splash' }
与 { type: 'About' } | { type: 'Splash' }
不同。由于您的变量 type
是所有可能判别式的并集,因此您正试图做到这一点,将一个键为 type
的对象分配给一个被判别联合 属性 的对象预计。
后两个示例之所以有效,是因为您几乎可以使用类型断言做任何事情。您实际上是在告诉编译器抑制它认为存在的类型错误。
要了解为什么这些类型不兼容,请考虑以下示例:
interface AboutCard {
type: 'About'
aboutMessage: string
}
interface SplashCard {
type: 'Splash'
spashMessage: string
}
export type Cards = AboutCard | SplashCard
export type CardType = Cards['type'] // no need to repeat string liteal types
const type = 'About' as CardType
// What properties should be required for `example1` ?
// since it is both types at the same time best case scenario would be to require all properties in teh union
const example1: Cards = {
type,
spashMessage: ""
}