6

I'm confused to why following errors, I have character interface

interface Character {
 race: "ORC" | "ELF" | "HUMAN" | "DWARF"
}

And another interface tavern

interface Tavern {
  races: Character['race'][]
}

Idea here is that races is an array of strings that can only be "ORC" | "ELF" | "HUMAN" | "DWARF"

For some reason I get an error when I use it like this

const tavern: Tavern = {
   races: ["ORC", "ELF", "HUMAN", "DWARF"]
}

Error reads as follows

[ts] Type '{ races: string[] }' is not assignable to type 'Tavern'. Types of property 'races' are incompatible. Type 'string[]' is not assignable to type '("HUMAN" | "ORC" | "ELF" | "DWARF")[]'. Type 'string' is not assignable to type '"HUMAN" | "ORC" | "ELF" | "DWARF"'.

2
  • 2.9.2, very weird, I'm not sure what else could be causing that error, will look into it more Commented Jul 24, 2018 at 18:23
  • 1
    Yeah, I didn't get any error either with your exact code. I was going to suggest a helpers function to infer the literal types instead of string but something este is at work typescriptlang.org/play/… Commented Jul 24, 2018 at 19:21

2 Answers 2

11

this is an old typescript story, you will most likely have to do this:

const tavern: Tavern = {
   races: ["ORC", "ELF", "HUMAN", "DWARF"] as Array<Character['race']>
}

possibly

type Race = "ORC" | "ELF"

const tavern: Tavern = {
   races: ["ORC" as Race, "ELF" as Race]
}

this should work

enum Race = { ORC, ELF }

interface Tavern {
  races: Race[]
}

const tavern: Tavern = {
   races: [Race.ORC, Race.ELF]
}
Sign up to request clarification or add additional context in comments.

2 Comments

That first one did the trick. Is there any source or github issue you could reference that explores this in more depth?
I am not sure about any references, but the problem is that typescripts treats your array as regular string[] initially. Btw, I have updated the answer - enums might be a good choice here, they can hold values as well like ORC = "ORC" if you want to have sane interop with other systems
0

I think this may have been a typescript bug when you wrote the question. Typescript v5.0.4 (the latest at the time of this answer) compiles your code without issue:

interface Character {
 race: "ORC" | "ELF" | "HUMAN" | "DWARF"
}

interface Tavern {
  races: Character['race'][]
}

const tavern: Tavern = {
   races: ["ORC", "ELF", "HUMAN", "DWARF"]
}

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.