Take a look at this TypeScript code:
'use strict';
type Value = 1 | 2 ;
type Owner = 'ownerA' | 'ownerB';
type ItemType = 'itemTypeA' | 'itemTypeB';
type Item = {
type: ItemType;
owner: Owner;
value: Value;
};
type AnotherType = {
[k in keyof Item]: null | {
[m in keyof Item[k]]: number;
};
};
const v: AnotherType = {
type: { itemTypeA: 0, itemTypeB: 1,},
owner: { ownerA: 0, ownerB: 1,},
value: null,
};
console.log(v);
When running tsc
, an error is thrown:
error TS2322: Type '{ itemTypeA: number; itemTypeB: number; }' is not assignable to type '{ [x: number]: number; toString: number; charAt: number; charCodeAt: number; concat: number; indexOf: number; lastIndexOf: number; localeCompare: …
The issue seems to be with the iteration of [m in keyof Item[k]]: number;
as it includes properties like charCodeAt and charAt which are not enumerable or present.
This behavior appears to contradict what the documentation on the 'keyof' type operator states:
The keyof operator takes an object type and produces a string or numeric literal union of its keys. The following type P is the same type as type P = "x" | "y":
type Point = { x: number; y: number }; type P = keyof Point;
According to the documentation, the produced union should only include 'x' and 'y', not non-enumerable values like 'charAt'.
It's possible that the issue lies with the in
operator, but in JavaScript, it only iterates through enumerable properties (not certain if this holds true in TypeScript when used as a type operator).
If anyone can provide insight into what's happening here, it would be greatly appreciated.