2

I have the following code which won't compile with TypeScript compiler 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'
}

I need the obj to stay as is. What I cannot do and not looking for in the answer:

  • using enums
  • declaring obj as a Basket

Is this a limitation of TypeScript compiler?

If so, is there workaround ? Will this be addressed in the future ?

1
  • 5
    The only thing I know of is explicitly telling TS that fruit in obj will be something that's contained in Fruit by doing obj = { fruit: 'apple' as const }. I'm not if you can somehow automatically enable this sort of inference in the compiler, though - the fact that you've declared fruit to be 'apple' now doesn't mean it can't change later if somebody does obj.fruit = 'lemon'. Commented Jan 13, 2020 at 10:05

1 Answer 1

2

The problem is that when you just declare obj its gets a wider type then Fruit is, so what you got is {fruit: string}, what is naturally not assignable to its sub-type. You can add as const

const obj = {
    fruit: 'apple' 
} as const

And such construct will be inferred as {fruit: 'apple'}, what is already assignable to Basket being its subtype.

You can also create such objects by value constructors. Consider:

const makeBasket = (fruit: Fruit): Basket => ({fruit})
const obj = makeBasket('apple'); // Basket object
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.