Repository navigation
Description
🔎 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
💻 Code
const record: Record<string, unknown> = {};
function foo<T extends string | false | null>(val: T) {
if (val) {
val;
//^?
bar(val);
record[val] = 5;
} else {
val
//^?
}
}
function foo2(val: string | false | null) {
if (val) {
val;
//^?
bar(val);
record[val] = 5;
} else {
val
//^?
}
}
function bar(val: string) {
return val;
}🙁 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 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.
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
Activity
Andarist commentedon Aug 22, 2024
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:brandonryan commentedon Aug 27, 2024
Mateusz Burzyński (@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?
Lordfirespeed commentedon Sep 8, 2024
brandonryan commentedon Sep 9, 2024
Lordfirespeed commentedon Sep 10, 2024
brandonryan commentedon Sep 10, 2024
Joe Clack (@Lordfirespeed)
Think this is what youre looking for
#50652