Issue
I am facing a simplified version of a problem with my model:
Here is how my model currently looks:
interface Instrument {
name: string;
// ...more properties shared by all instruments...
}
interface Guitar extends Instrument {
type: "classical" | "electric";
// ...additional properties specific to guitars...
}
interface Flute extends Instrument {
range: "concert" | "piccolo" | "g-alto" | "g-bass";
// ...properties unique to flutes...
}
interface Artist {
instrument: Guitar | Flute;
}
Whenever I introduce a new instrument, I have to remember to update the list of accepted instruments for artists. I am exploring if there's a way to create an abstract instrument interface and have Artist.instrument
accept all interfaces that extend Instrument
.
Desired Solution
I envision a scenario like this:
interface Artist {
instrument: // anything that extends the Instrument interface
}
I'm open to alternative solutions as well. Please suggest if there's a simpler way to tackle this issue.
Attempts Made So Far
I initially tried assigning Instrument
as the type for Artist.instrument
, but it didn't work as expected.
interface Artist {
instrument: Instrument
}
interface Guitar extends Instrument {
type: "classical" | "electric";
}
const guitar: Guitar = {
name: "Guitar",
type: "electric"
}
const jimiHendrix: Artist = {
instrument: {
name: "Guitar",
type: "electric"
}
}
However, this approach resulted in the following error:
TS2322: Type '{ name: string; type: string; }' is not assignable to type 'Instrument'. Object literal may only specify known properties, and 'type' does not exist in type 'Instrument'.