-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Narrow object property when key is a variable #56389
Comments
I saw the title of this issue, clicked, and was all ready to dupe it to #10530... then I saw who posted it π
Indeed, the refocusing was long overdue, IMO. It's so confusing to have to explain that "yeah this is still a dupe of 10530 even though the OP there uses a literal key which actually works now and has for a long time". Especially since that makes this look even more like a bug than it already did. |
Huh, never knew about the second part. |
This does not currently work well. See microsoft/TypeScript#56389
π Search Terms
type guard, narrowing, control flow analysis, property, variable index, bracket notation
β Viability Checklist
β Suggestion
This is a re-opening or re-focusing of #10530. The original motivating example (narrowing
obj
via checkingobj["key"]
the same way asobj.key
when"key"
is the discriminant property) was fixed a long time ago, but the issue stayed open and started collecting requests for a more general feature of narrowing object properties by bracket access. Other issues about the general feature were closed as duplicates. But now #10530 is closed, and any unmet needs from there should be moved to a new issue. Like this one, maybe:Please enable narrowing of object properties accessed via bracket notation based on the identity of the key, not just its type. If
guard()
is a type guard, thenif guard(obj[key]) { β― obj[key] β― }
should serve to narrowobj[key]
inside the block, no matter what the type ofkey
is.π Motivating Example
Currently narrowing
obj[key]
only works ifkey
is actually a string literal or aconst
of a single string literal type:But superficially similar constructions do not work, where
key
is notconst
, and where the type is a wide type likestring
, or a union type like"a" | "b"
, or a generic type likeK extends string
:It would be great if all of those would "just work" (although I can understand why it's not trivial to do so, or that one can imagine some cases where it would be a bad idea to allow it).
π» Use Cases
See #10530 and various issues closed as duplicates for more use cases.
The standard workaround is to assign the property to a new
const
and do the guarding on that:This works well, although people on Stack Overflow often express dissatisfaction with that suggestion (e.g., "why should I have to create a new variable just to appease TypeScript?").
Unfortunately some folks also expect to be able to assign something to the narrowed property, and there's just no great way to do that without type assertions:
The text was updated successfully, but these errors were encountered: