The explanation of keyof
for index signatures in the Typescript handbook makes no sense.
From here: https://www.typescriptlang.org/docs/handbook/2/keyof-types.html
The following example is presented:
type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish;
// type A = number
type Mapish = { [k: string]: boolean };
type M = keyof Mapish;
// type M = string | number
With the explanation:
Note that in this example,
M
isstring | number
— this is because JavaScript object keys are always coerced to astring
, soobj[0]
is always the same asobj["0"]
.
That makes no sense.
What is different about type M
isn't the presence of the string
type, since the index was declared as string
in the first place, what's different is the presence of the number
type which the explanation does not address.
Also if the type string
is present because "object keys are always coerced to a string", then why is string
not listed as one of the key types for type A
where the index is of declared type number
?
UPDATE In response to H.Bs answer
If the key is specified to be number, then only number is allowed because not every string can be converted to a number.
But the following both compiles and runs, suggesting that specifiing the index using either number
or string
is valid in Typescript and Javascript irrespective of the difference in the Typescript type of the indexed access type.
let a1: Arrayish = {};
a1[0] = 4;
a1["2"] = 6; // Index declared as number but can be set with string.
console.log(a1);
let m1: Mapish = {};
m1[0] = true;
m1["2"] = false;
console.log(m1);
(Tested in the Typescript Playground)
I would think of it in terms of valid conversions.
If the key is specified to be number
, then only number is allowed because not every string
can be converted to a number. If the key is specified as string
however, then number
becomes valid as well, because all numbers can be turned into strings, and that is what happens implicitly in JS.
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