-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Implicit index signatures for enum object types #31687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@typescript-bot run dt |
Heya @ahejlsberg, I've started to run the extended test suite on this PR at bb15df3. You can monitor the build here. It should now contribute to this PR's status checks. |
Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at bb15df3. You can monitor the build here. It should now contribute to this PR's status checks. |
const v2 = getStringIndexValue(E2); | ||
const v3 = getStringIndexValue(E3); | ||
const v4 = getNumberIndexValue(E1); | ||
const v5 = getNumberIndexValue(E2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this unknown
and not an error? (Is it just because inference fails and "a thing with an inferrable index" is assignable to a {[x: number]: unknown}
?) I'd think that yeah, E2
has an inferrable index type, sure, but we know that it has no numbers in it at all. But, from the stance that the number index signature (were it present in the type) would need to be assignable to the string index, this'd need to be E2
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we infer nothing for T
in the call to getNumberIndexValue
. Keep in mind we're not doing an assignment here, we're just doing inference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we are doing an assignment - we're saying that a {[x: string]: E2}
is assignable to a {[x: number]: unknown}
. I guess the output type here just irks me a tad - it could only possibly be an E2
or keyof typeof E2
, rather than an unknown
.
Like, if I write enum StrNum { Zero = "0", One = "1" }
, indexing by 0
or 1
is gunna get me Zero
or One
, likewise if I write enum NumStr { "0" = "Zero", "1" = "One" }
, indexing by Zero
or One
is gunna get me "0"
or "1"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, indexing your StrNum
by 0
or 1
is going to get you undefined
(there's no reverse mapping for string valued members), and NumStr
is an error because members can't have numeric names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, the unknown
type is consistent with what we infer for object literal types that have no numerically named members. In some sense it would be more consistent to return undefined
since that's what you're going to get, but that really is an orthogonal issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no reverse mapping for string valued member
I always forget about that.
Anyway, the unknown type is consistent with what we infer for object literal types that have no numerically named members
Oh, ick. Ok.
Types representing object literals or modules have inferable index signatures because their exact set of properties is known. This PR implements the same behavior for types representing enum objects since these also have exact and close ended sets of properties.
The enum object type of an enum with at least one numerically valued member has an implicit string index signature of type
string | X
, whereX
is a union of the types of all numerically valued members, and an implicit numeric index signature of typestring
.The enum object type of an enum with only string valued members has an implicit string index signature of type
string
and no implicit numeric index signature.In the above,
X
reflects the reverse mapping from strings to numeric enum values included in the generated code that initializes the enum object.Fixes #30977 (to the extent we can fix it).