Reputation: 451
Here is the code
class A {
x = 0;
y = 0;
visible = false;
render() {
}
}
type RemoveProperties<T> = {
readonly [P in keyof T]: T[P] extends Function ? T[P] : never//;
};
var a = new A() as RemoveProperties<A>
a.visible // never
a.render() // ok!
I want to remove " visible / x / y " properties via RemoveProperties ,but I can only replace it with never
Upvotes: 42
Views: 21382
Reputation: 74490
You can use as
clauses in mapped types to filter out properties in one go:
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
type A_Methods = Methods<A>; // { render: () => void; }
When the type specified in an
as
clause resolves tonever
, no property is generated for that key. Thus, anas
clause can be used as a filter [.]
Further info: Announcing TypeScript 4.1 - Key Remapping in Mapped Types
Upvotes: 75
Reputation: 249486
You can use the same trick as the Omit
type uses:
// We take the keys of P and if T[P] is a Function we type P as P (the string literal type for the key), otherwise we type it as never.
// Then we index by keyof T, never will be removed from the union of types, leaving just the property keys that were not typed as never
type JustMethodKeys<T> = ({[P in keyof T]: T[P] extends Function ? P : never })[keyof T];
type JustMethods<T> = Pick<T, JustMethodKeys<T>>;
Upvotes: 60