Given an interface (from an existing .d.ts file that can\'t be changed):
interface Foo {
[key: string]: any;
bar(): void;
}
Is there a
There is a way, requiring TypeScript 2.8's Conditional Types.
It is based on the fact that 'a' extends string
but string
doesn't extends 'a'
interface Foo {
[key: string]: any;
bar(): void;
}
type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;
type FooWithOnlyBar = Pick<Foo, KnownKeys<Foo>>;
You can make a generic out of that:
// Generic !!!
type RequiredOnly<T extends Record<any,any>> = Pick<T, KnownKeys<T>>;
type FooWithOnlyBar = RequiredOnly<Foo>;
For an explanation of why exactly KnownKeys<T>
works, see the following answer:
https://stackoverflow.com/a/51955852/2115619
There is not a really generic way for it, but if you know which properties you need, then you can use Pick:
interface Foo {
[key: string]: any;
bar(): void;
}
type FooWithOnlyBar = Pick<Foo, 'bar'>;
const abc: FooWithOnlyBar = { bar: () => { } }
abc.notexisting = 5; // error
Not really. You can't "subtract" something an interface like this one. Every member is public and anyone claiming to implement Foo
, must implement them. In general, you can only extend interfaces, via extends
or declaration merging, but not remove things from them.