Type guards not working for indexed types with generics
See original GitHub issueTypeScript Version: 2.7
Search Terms: indexed type guard
Code
function f<T extends string>(q: {[k:string]: number | string}, t: T) {
const v= q[t];
if (typeof(v)!=="string") {
const vv: number = v;
}
}
Expected behavior:
Type of v
is string|number
, and in the if
it is just number. Compiles.
Actual behavior:
Assignment to vv
doesn’t compile: string not assignable to number. When hovering, type of v
is { [k: string]: string | number; }[T]
, so eliminating string from it does not change the type, it is still the same, and only when assigning to vv
it gets resolved to string|number
which then causes compilation error.
Changing type of t
to string fixes the problem. The problem also appears if q
has type keyed by [k in T]
.
Playground Link: link
Related Issues:
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:6 (4 by maintainers)
Top Results From Across the Web
Why does Typescript not infer the type for a generic type guard ...
I found a solution ! I can use the same technique like sequelize uses it in its typings for the model attribute types....
Read more >Generic type guard in Typescript - DEV Community
But we get this error: Type 'T' cannot be used to index type 'typeMap'. In the case where T is not a constructor...
Read more >Documentation - Advanced Types - TypeScript
A type guard is some expression that performs a runtime check that guarantees the type in some scope. Using type predicates. To define...
Read more >How To Do Anything in TypeScript With Type Guards
Type guards are conditional checks that allow types to be narrowed from ... we check exists in multiple cases, the narrowing will not...
Read more >Generics - TypeScript
While using any is certainly generic in that it will cause the function to accept any and all types for the type of...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Narrowing with primitives really does not work with generics… here is a simpler example:
The issue here is that
T
has to stay generic. any narrowing we do has to be on the type of the constraint, so inif
blockt
should beT extends number
instead ofT extends number | string
.The problem is that this is a regression - my original example, or something equivalent to it, used to work in some earlier version (I’m not sure which exactly) because
q[t]
was immediately treated asstring | number
, at least in the case when the key was declared as[k in T]
. So I’m quite sure this is a bug, not just a suggestion.I think that this is why @mhegazy’s example is different than mine, where the type does not really depend on T.