There is a difference between both types.
type MyObject = { [_: string]: string | number }
type MyObjectAlternative = Record<string, string | number>
You can't use unions in MyObject ( in TypeScript before 4.4):
type MyObject = { [_: string | number ]: string | number } // error
type MyObjectAlternative = Record<'a'|'b', string | number> // ok
type MyObject = { [_: 'a'|'b' ]: string | number } // error
type MyObjectAlternative = Record<'a'|'b', string | number> // ok
An index signature parameter type cannot be a union type. Consider using a mapped object type instead
From T.4.4 (currently beta) you can use union as a type of a key in MyObject.
type MyObject = { [_: string | number | symbol]: string | number } // allowed
type MyObjectAlternative = keyof Record<'a' | 'b', string | number> // ok
type Keys = {
[Prop in keyof MyObject]: Prop
}
type Keys2 = {
[Prop in keyof MyObjectAlternative]: Prop
}
As you might have noticed, keyof MyObject and keyof MyObjectAlternative operators works differently in both cases.
MyObjectAlternative is more treated like regular object in javascript with all built in properties, while MyObject is treated as object without prototype.
Also, since TS 4.4 we can mix template literal strings:
type MyObject = { [_: `data-${string}`]: string | number } // ok
But please keep in mind
type MyObject = { [_: 'a'|'b']: string | number } // error
union of literals still disallowed
Typescript 4.4
Record.Recordwas something Typescript didn't initially have, so creating simple types for Objects used the first version. IOW: it could be partially legacy reasons the first version exists. Edit, just checked, it wasn't until version 2.1 the Record type was introduced. typescriptlang.org/docs/handbook/release-notes/…Recordis just a tad easier, before using it, I always seemed to have to lookup again how to do it. Since usingRecordI've not needed too.