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.