You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Error on line 8, cannot use val to index object type with string key.
Val appears to be narrowed to NonNullable<T> yet I can use it as string when calling functions?
Note: foo2 does not use generics and has more expected bahavior.
π Expected behavior
type Falsy = false | null | undefined | 0 | "";
(might remove 0 | "" from this because that gets into negated types... false seems like a common enough one to matter though)
On line 5 inside of the if check, I expect val to be narrowed to Exclude<T, Falsy> but instead, is incorrectly (imo) narrowed to NonNullable<T> which does not exclude false.
What is exceptionally strange, is that the type narrowing behavior seems to differ depending on how val is used. I can pass it to the function that takes a string parameter, but when I try to use it to index an object on line 8, I get an error.
Relates to #15576 and #43183 , only expressions in the element access expressions are subject to constraint-based narrowing (you'd like to narrow argument expressions here). We can find this comment in the current implementation of isConstraintPosition:
// In an element access obj[x], we consider obj to be in a constraint position, except when obj is of// a generic type without a nullable constraint and x is a generic type. This is because when both obj// and x are of generic types T and K, we want the resulting type to be T[K].
@Andarist not sure if you are meaning this is intended behavior, or a bug.
Is there anything else I need to do to prevent this from getting buried in the 5K+ other issues?
π Search Terms
generic truthy narrowing generic index
π Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about narrowing truthy generic types
β― Playground Link
https://www.typescriptlang.org/play/?ts=5.7.0-dev.20240821&ssl=29&ssc=2&pln=1&pc=1#code/MYewdgzgLgBATgU1HAJgLhgJSSVAeaOASzAHMAaGAVzAGswQB3MAPhgF4YBvAXwG4AsAChhAMxrAoRcDFEgQeACowEADygIwKCDEIlSMAD6yAhgBsICIzDBUzZlgAoAbuYyKAlN2ExfMIqIwLuZeXD5+Ea5mgkIREQD08QB6APzhcTAARiZwwWYeMRm+iMgoANpRALocMACshX48KhZWYbFFUelxialdPML9IkLiYJLSYLLyAEx5GHpk1qLmlta29qFdAUFRG+0ZUQ0ZPWl7cdm5O4dxJbjlVTX1fc0rbUUwnacJyScRg4NiEikMnOs10UGIZF2EUQUCocAmBwGQA
π» Code
π Actual behavior
Error on line 8, cannot use val to index object type with string key.
Val appears to be narrowed to
NonNullable<T>
yet I can use it as string when calling functions?Note:
foo2
does not use generics and has more expected bahavior.π Expected behavior
type Falsy = false | null | undefined | 0 | "";
(might remove
0 | ""
from this because that gets into negated types... false seems like a common enough one to matter though)On line 5 inside of the if check, I expect val to be narrowed to
Exclude<T, Falsy>
but instead, is incorrectly (imo) narrowed toNonNullable<T>
which does not exclude false.What is exceptionally strange, is that the type narrowing behavior seems to differ depending on how
val
is used. I can pass it to the function that takes a string parameter, but when I try to use it to index an object on line 8, I get an error.Additional information about the issue
This issue was discussed in detail by others more experienced than me in this typescript discord thread:
https://discord.com/channels/508357248330760243/1275942751724372110
Invite to server if you aren't a member:
https://discord.com/invite/typescript
The text was updated successfully, but these errors were encountered: