I'm new to typescript and there's still a lot to study but I've stumble with this code that is quite confusing for me about the Record utility types.
This code works on the playground
const data = async (name: string, id: number): Promise<Record<number,string>> => {
const obj = {
foo: 'bar', //shouldn't this not work since I've used 'number'?
}
return obj
}
This one does not (2nd line)
const foo1: Record<string, string> = { foo: 'bar' }
const foo2: Record<number, string> = { foo: 'bar' }
Why is this? I am also not sure what kind of data type should be used in the 'key'. Try typescript playground
This is because TS should be compatible with JavaScript.
Consider this pure js code:
const foo={
0:42
}
const x = foo['0'] // number
const y = foo[0] // number
As you might have noticed, JS allows you to use both string and number key for 0: 42
See both js and ts docs:
js explanation
Property names Property names are string or Symbol. Any other value, including a number, is coerced to a string. This outputs 'value', since 1 is coerced into '1'.
ts explanation
It is possible to support both types of indexers, but the type returned from a numeric indexer must be a subtype of the type returned from the string indexer. This is because when indexing with a
number, JavaScript will actually convert that to astringbefore indexing into an object. That means that indexing with100(anumber) is the same thing as indexing with"100"(astring), so the two need to be consistent.
Why is this? I am also not sure what kind of data type should be used in the 'key'.
TypeScript has built in type for key: type PropertyKey = string | number | symbol
You can use PropertyKey without declaration. This type is built in
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With