I want to create a type for an object with string keys and arbitrary values. Thus, my desired type (let's call it Obj) should cause a type error for the following obj object because its key is of type number:
const obj: Obj = {
1: "foo" // I'd expect a TS error here because the key 1 is of type `number` and not `string`
};
However, all of my attempts don't cause any TS error! Here are my three attempts:
- Built-in
Recordtype (which implicitly uses theinoperator):
type Obj = Record<'1', any>;
const obj: Obj = {
1: "foo" // TS error expected! ❌
};
- Mapped type (to recreate
Recordtype):
type Obj = { [key: string]: any };
const obj: Obj = {
1: "foo" // TS error expected! ❌
};
- Custom
Recordtype with key remapping viaas:
type MyRecord<K extends string, T> = {
[P in K as string]: T;
};
type Obj = MyRecord<string, any>;
const obj: Obj = {
1: "foo" // TS error expected! ❌
};
- Even using a literal type
'1'does not enforce the key to be'1', but allows the number1:
type Obj = Record<'1', any>;
const obj: Obj = {
1: "foo" // TS error expected! ❌
};
Is it in general possible, or is it due to some property of a JavaScript object that it's not possible?