Home > Mobile >  Is it possible to filter out keys from an interface / type?
Is it possible to filter out keys from an interface / type?

Time:11-11

For example, I have an interface:

interface Foo {
  name: string;
  id: number;
}

And I only want the keys of type string. I managed to change the type of id to never and get all the keys from Foo. But id is still a valid key, just with type never.

const bar: keyof Partial<{ [K in keyof Foo ]: Foo [K] extends string ? Foo [K] : never }> = 'id';

How do I get the keys from Foo of type string only?

What I want is:

const bar: FooStringKeys = 'name'; // ok
const bar: FooStringKeys = 'id;    // error

CodePudding user response:

Adopted from the mapped types docs. TS Playground version here.

interface Foo {
  name: string;
  id: number;
}

// Generic string property extractor
type StringsOnly<Type> = {
    [Property in keyof Type as Extract<Property, Type [Property] extends string ? Type [Property] : never>]: Type[Property]
};

// Foo *string* Properties
type FooString = StringsOnly<Foo>

const fooString: FooString = {name: 'hello'}
const notFooString: FooString = {id: 2} // error

// Foo *string* Key names
type FooStringKey = keyof FooString

const fooStringKey: FooStringKey = "name"
const notFooStringKey: FooStringKey = "id" // error
  • Related