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.
>Solution :
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
}