Reputation: 44376
Here is what I would like:
const a = getNumber({a: 3, b: "three"}, "a"); // a is type of number (or even 3)
const b = getNumber({a: 3, b: "three"}, "b"); // does not compile
The closest I have gotten is
type NumberOnly<T> = {
[k in keyof T]: T[k] extends number ? number : never;
}
const getNumber = <T extends Record<string, any>,
K extends keyof NumberOnly<T>>(t: T, k: K):NumberOnly<T>[K]
=> t[k];
a
is type number
and b
is ... never
.
Close but no cigar.
The suggestion here only works if the base type is fixed, which weirdly would have worked for my original problem, but if the type is generic, Typescript does not understand that t[k]
is a number.
Upvotes: 1
Views: 251
Reputation: 23825
This should fix the problem:
type NumberOnly<T> = {
[K in keyof T as T[K] extends number ? K : never]: T[K]
}
We use the as
operator inside the index signature. When T[K]
is not number
the key will be omitted.
Upvotes: 1