Ramesh Reddy
Ramesh Reddy

Reputation: 10662

How to filter an interface using conditional types in TypeScript?

I'm trying to create a type that takes an interface as a generic type parameter and filters out properties whose values are not strings.

This is what I have:

interface Bla {
    key1: string;
    key2: number;
    key3: string;
    key4: boolean;
}

type PickStrings<T> = {
    [K in keyof T]?: T[K] extends string ? T[K] : never;
}

const bla: PickStrings<Bla> = { // should error as key3 is not present 
    key1: 'string',
}

Playground

The problem with using [K in keyof T]? is it doesn't error as keys become optional. But, if I use [K in keyof T] it is checking for the existence of all keys in the interface.

How can I fix this?

Upvotes: 0

Views: 497

Answers (1)

Teneff
Teneff

Reputation: 32158

You can create a type to extract the keys by type and then use it with Pick

type PickKeysByValueType<T, TYPE> = {
    [K in keyof T]: T[K] extends TYPE ? K : never
}[keyof T]

type PickStrings<T> = Pick<T, PickKeysByValueType<T, string>>

Playground

Upvotes: 1

Related Questions