键入注释和区分字符串文字的联合

问题描述 投票:1回答:1

我一直遇到这个问题,创建符合类型注释的对象(下例中的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设置为字符串文字AboutSplash它工作正常,它就是它可能是它有问题的歧视联盟。

对不起,我不知道如何更好地问这个!

我觉得这可能是这样的:why is TypeScript converting string literal union type to string when assigning in object literal?提供了一些关于为什么会发生这种情况的线索?

typescript string-literals discriminated-union
1个回答
1
投票

除了没有其他属性的琐碎案例,{ 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: ""
}
© www.soinside.com 2019 - 2024. All rights reserved.