Hur man läser värdet av en Record i TypeScript (på rätt sätt)


Jag har följande två typer

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

Nu har jag några föremål:

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

och jag försöker läsa värdet av version i value-objektet

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

men jag får felet:

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

I konsolen kan jag faktiskt se att värdet desc skrivs ut men jag får detta fel i VS Code. Jag skulle kunna undvika detta fel genom att kasta SortOption-objektet till any

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

men detta ser ut som en smutsig hack och jag skulle vilja veta hur jag kan lösa detta på ett korrekt sätt.

Svar #1

Du har definierat SortOption som denna typ:

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

Det betyder att item.value kan vara en string eller det kan vara en Record<string, 'desc' | 'asc'>.

Till exempel, detta är också ett giltigt Item:

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

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

Och om du vill behandla värdet som ett Record måste du först bevisa att det är ett vid körning för att begränsa typen.

Till exempel:

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

Se lekplats