Typescript index signatures
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