Reputation: 28462
I'm trying to create an object where all values are of type SFXElem
.
Is it possible to tell TS that every value needs to be of type SFXElem? Just like Array<string>
knows that every value in the array will be a string?
interface SFXElem {
path: string,
audio?: Audio
}
// This doesn't work: Error "Type 'Object' is not generic
const sfxDir1: Object<SFXElem> = {
sound1: {path: "something.mp3"},
sound2: {path: "other.mp3"},
}
// This could work, but I can sneak other types if I don't use <SFXElem> on every line
const sfxDir2 = {
sound1: <SFXElem>{path: "hi"},
sound2: <SFXElem>{path: "ho"},
sound3: {other: "hello"} // Allowed
};
Is there a way to tell TypeScript that only SFXElem
types are allowed as object values?
I tried using Record<string, SFXElem>
, as suggested by CRice, but that lets me access properties that don't exist. In the demo below, accessing the doesntExist
property is allowed, when it should yield an error.
Upvotes: 4
Views: 1250
Reputation: 26607
You can use Record
by listing names of properties that you want to allow:
const sfxDir3: Record<"sound1" | "sound2", SFXElem> = {
sound1: {path: "something.mp3"},
sound2: {path: "other.mp3"},
};
It seems you are creating chicken-egg problem here. If you want to allow "any" property name on the type and only to constrain property type, then your 2nd example Record<string, SFXelem>
is valid.
This would be valid usage for that case, to add extra property after initialization:
const sfxList2: Record<string, SFXElem> = {
sound1: {path: "something.mp3"},
sound2: {path: "other.mp3"},
};
sfxList2.doesntExistsYet = {path: "yet-another.mp3"};
Upvotes: 3
Reputation: 867
You can use Index Signatures.
interface SFXObject: {
[index: string]: SFXElement
}
This way you can make an object of type SFXObject
and every string property will need to be an SFXElement
.
So in your case something like this:
const sfxDir1: SFXObject = {
sound1: {path: "something.mp3"},
sound2: {path: "other.mp3"},
sound3: {other: "hello"} // Not allowed
}
Documentation here: https://www.typescriptlang.org/docs/handbook/2/objects.html
Upvotes: 3