Reputation: 340
I have defined a static object :
const instruments = {
"guitar": {
tunings: ["E","A","D","G","B","E"]
},
"ukulele": {
tunings: ["G","C","E","A"]
},
"baritone": {
tunings: ["D","G","B","E"]
},
"mandolin": {
tunings: ["G","G","D","D","A","A","E","E"]
},
"bass": {
tunings: ["E","A","D","G"]
}
}
and want to call a function with the name of the instrument I am referencing to obtain appropriate 'tunings' array :
constructor(canvas : HTMLCanvasElement, tuningName : string, startFret = 0, noFrets : number) : any {
const tuningsArr = instruments[tuningName].tunings;
...
}
however VSCode tells me that's not valid Typescript. How can I achieve getting a reference to the correct tunings array from the passed string?
Upvotes: 0
Views: 1144
Reputation: 1075219
There are a couple of ways to do that.
You can use the type inferred for the instruments
const, but to do that, you have to tell TypeScript that the state of the instruments
object is constant using as const
:
const instruments = {
"guitar": {
tunings: ["E","A","D","G","B","E"]
},
"ukulele": {
tunings: ["G","C","E","A"]
},
"baritone": {
tunings: ["D","G","B","E"]
},
"mandolin": {
tunings: ["G","G","D","D","A","A","E","E"]
},
"bass": {
tunings: ["E","A","D","G"]
}
} as const;
// ^^^^^^^
Then, constrain the type of tuningName
to keyof typeof instruments
(a valid key for the type that instruments
has), requiring that it be a valid key for that (now constant) object:
class Example {
constructor(canvas : HTMLCanvasElement, tuningName : keyof typeof instruments, startFret = 0, noFrets : number) : any {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^
const tuningsArr = instruments[tuningName].tunings;
// ...
}
}
Alternatively, you could declare types explicitly and assign instruments
the type for instruments:
interface Tuning {
tunings: string[]; // You could even nail this type down more if you wanted
}
interface Instruments {
guitar: Tuning;
ukulele: Tuning;
baritone: Tuning;
mandolin: Tuning;
bass: Tuning;
}
const instruments: Instruments = {
"guitar": {
tunings: ["E","A","D","G","B","E"]
},
"ukulele": {
tunings: ["G","C","E","A"]
},
"baritone": {
tunings: ["D","G","B","E"]
},
"mandolin": {
tunings: ["G","G","D","D","A","A","E","E"]
},
"bass": {
tunings: ["E","A","D","G"]
}
};
Then it's keyof Instruments
rather than keyof typeof instruments
:
class Example {
constructor(canvas : HTMLCanvasElement, */tuningName : keyof Instruments, startFret = 0, noFrets : number) : any {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^
const tuningsArr = instruments[tuningName].tunings;
// ...
}
}
Upvotes: 1