Michael Lorton
Michael Lorton

Reputation: 44376

Omitting keys of a particular type

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

Answers (1)

Tobias S.
Tobias S.

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.

Playground

Upvotes: 1

Related Questions