复合类型中的TypeScript字符串联合类型推断问题

复合类型中的TypeScript字符串联合类型推断问题,typescript,Typescript,我有以下代码,不能用TypeScript编译器编译3.7.3 type Fruit = 'apple' | 'banana' const val = 'apple' // Works. TS remembers the value of `val` const fruit: Fruit = val type Basket = { fruit: Fruit } const obj = { fruit: 'apple' } // Error: Type 'string'

我有以下代码,不能用TypeScript编译器编译
3.7.3

type Fruit = 'apple' | 'banana'

const val = 'apple'

// Works. TS remembers the value of `val`
const fruit: Fruit = val

type Basket = {
    fruit: Fruit
}

const obj = {
    fruit: 'apple' 
}

// Error: Type 'string' is not assignable to type 'Fruit'.
// TS probably discarded that `fruit` property has concrete value and treats it as any `string`.
const structuralBasket: Basket = obj

// This works 
const declaredBasket: Basket = {
    fruit: 'apple'
}
我需要
obj
保持原样。我不能做的事,我不在答案中寻找:

  • 使用枚举
  • obj
    声明为
    Basket
这是TypeScript编译器的一个限制吗


如果有,是否有解决办法?这将在将来得到解决吗?

问题是,当您只声明
obj
时,它会得到一个更宽的类型,而
则是,因此您得到的是
{Fruit:string}
,它的子类型自然无法赋值。您可以将
添加为const

const obj = {
    fruit: 'apple' 
} as const
这样的构造将被推断为
{fruit:'apple'}
,已经分配给
Basket
的是它的子类型

您还可以通过值构造函数创建此类对象。考虑:

const makeBasket = (fruit: Fruit): Basket => ({fruit})
const obj = makeBasket('apple'); // Basket object

我所知道的唯一一件事就是明确地告诉TS,
obj
中的
fruit
将是
fruit
中包含的内容,方法是执行
obj={fruit:'apple'as const}
。不过,我不知道你是否能在编译器中自动启用这种推理——你现在将
fruit
声明为
'apple'
并不意味着以后如果有人这样做了
obj.fruit='lemon'
,它就不能更改。