I wish to restrict the assignable types of an object to a specific type. Example, an object where all keys must have number
values, such as below:
interface NumberMap {
[key: string]: number;
}
This works for enforcing the value restriction however I then won't be able to determine what keys actually exist inside the map
variable.
const map: NumberMap = {
one: 1,
two: 2,
three: 3,
};
// no error, but incorrect, this key does *not* exist
const lol = map.weoiroweiroew;
// Also cannot do this
type MyKeys = keyof map;
Is there a way to enforce an index signature without losing the information of what keys the object implementing that signature has?
Index signature is used to represent the type of object/dictionary when the values of the object are of consistent types. Syntax: { [key: KeyType] : ValueType } Assume that we have a theme object which allows us to configure the color properties that can be used across the application.
The error "Property is incompatible with index signature" occurs when a property is not compatible with the specified type of the index signature. To solve the error, change the type of the property or use a union to update the type in the index signature.
The {[key: string]: string} syntax is an index signature in TypeScript and is used when we don't know all the names of a type's properties ahead of time, but know the shape of the values. The index signature in the examples means that when an the object is indexed with a string , it will return a string .
A TypeScript Interface can include method declarations using arrow functions or normal functions, it can also include properties and return types. The methods can have parameters or remain parameterless.
The only way to do both restrict values, and preserve type information about what keys are actually in the implementing type is to use a generic helper function. The function will enforce that the object literal extends the interface, but it will infer the actual type of the object literal:
interface NumberMap {
[key: string]: number;
}
function createNumberMap<T extends NumberMap>(v: T) {
return v;
}
const map = createNumberMap({
one: 1,
two: 2,
three: 3,
// no: '' // error
});
map.one //ok
map.no //error
How about this ? I think this will restrict your objects keys to the given 3 indexes
type Index = 'one' | 'two' | 'three'
type NumberMap = { [k in Index]?: number }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With