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