Home > Net >  How to read the value of a Record in typescript (the right way)
How to read the value of a Record in typescript (the right way)

Time:06-16

I have the following two types

type SortOption = string | Record<string, "desc" | "asc">
type Item = { name: string, value: SortOption}

Now I have a some items:

const item: Item = {
  name: "myItem",
  value: {
    version: "desc"
  }
}

and I try to read the the value of version in value object

console.log(item.value.version) // prints "desc" but shows error

but I'm getting the error:

Property 'version' does not exist on type 'SortOption'.
  Property 'version' does not exist on type 'string'.ts(2339)

In the console I can actually see that the value desc is printed out but I get this error in vs code. I could avoid this error by casting the SortOption object to any

console.log((item.value as any).version) // prints "desc" but doesn't show error

but this looks like a dirty hack and I would like to know how I can solve this in a proper way.

CodePudding user response:

You've defined SortOption as this type:

type SortOption = string | Record<string, "desc" | "asc">

That means that item.value might be a string or it might be a Record<string, 'desc' | 'asc'>.

For instance, this is also a valid Item:

const item: Item = {
  name: "myItem",
  value: 'a string'
}

// but now this will throw an exception at runtime:
item.value.version

And if you want to treat the value like a Record you have to prove it is one first at runtime in order to narrow down the type.

For example:

// if it's not a string, it must be the other thing.
if (typeof item.value !== 'string') {
    console.log(item.value.version) // fine
}

See playground

  • Related