Reputation: 2510
We've been working on a larger project and different developers seem to use different type definitions for a fairly plane object, more precisely two versions stood out. Can anybody explain main differences, benefits, and implications of using either version?
type MyObject = { [_: string]: string | number }
type MyObjectAlternative = Record<string, string | number>
Cheers
Upvotes: 1
Views: 295
Reputation: 33041
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
Upvotes: 1
Reputation: 11495
Record
is the same as type literal. If you look at the definition of Record
you will see this:
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
Upvotes: 1