I have the following type - export type Sizes = 'small' | 'medium' | 'big'
and I want to use this type as keys for an object I'm creating:
type SizeInformation = {
[key in Sizes]: string;
}
However, the desired functionality here is that this type (and therefore the object that will be created based on it) doesn't necessarily need to have all keys named, or none at all, but if a key goes into the object, it should be of type Sizes
.
As such, an empty object would be valid, an object with just the key medium
would also be valid, but if an object has the keys medium
and sea
, it is not valid, as, again, all keys need to be of type Sizes
.
I've played around with Partial
but to no avail.
How can I achieve that? Thank you.
CodePudding user response:
You should leave your index signature the same. Index signatures are stating for what the shape of properties/values would be if they were enumerable (or actually assigned). Therefore, you should always have your index signatures as non-undefined. If you want strict index signature access where you need to handle for a key not being in the object, then you should enable the noUncheckedIndexedAccess
config property because it will force you to handle for the undefined
case when using index signatures. See the reference on noUncheckedIndexedAccess
CodePudding user response:
It is very simple. You can use two Utility Types
, Partial
and Record
, together.
type Sizes = 'small' | 'medium' | 'big'
// Following code will create type that can accept keys which are of type Sizes and which will be optional
type SizeInformation = Partial<Record<Sizes, string>>;
const obj : SizeInformation = {
big: 'big',
medium: 'medium',
small:'small'
}
For reference https://www.typescriptlang.org/docs/handbook/utility-types.html