I'm trying to type an object so that its' keys are all of a specific type, but in such a way that I still get intellisense when I access the the main object.
interface ObjectWithKeysOf<T>
{
[key: string]: T;
}
const TEST: ObjectWithKeysOf<number> =
{
prop1: 1,
prop2: 2
};
Given the above, I hoped that the following would work, but it doesn't. Intellisense doesn't suggest prop1
as a property, and the code fails to compile.
const aNumber = TEST.prop1;
Is this possible?
CodePudding user response:
You can use the satisfies
operator — introduced in TypeScript v4.9
— to constrain a type while preserving its specifics (including IntelliSense autocompletion):
Try it out in the TS Playground:
const test = {
prop1: 1,
prop2: 2,
} satisfies Record<string, number>;
test.prop1;
//^? (property) prop1: number
test.prop2;
//^? (property) prop2: number
test.prop3; /*
~~~~~
Property 'prop3' does not exist on type '{ prop1: number; prop2: number; }'. Did you mean 'prop1'?(2551) */
The same example, but combined with a const
assertion:
const test = {
prop1: 1,
prop2: 2,
} as const satisfies Record<string, number>;
test.prop1;
//^? (property) prop1: 1
test.prop2;
//^? (property) prop2: 2
test.prop3; /*
~~~~~
Property 'prop3' does not exist on type '{ readonly prop1: 1; readonly prop2: 2; }'. Did you mean 'prop1'?(2551) */
See also the type utility Record<Keys, Type>
.