How to create a type excluding instance methods from a class in typescript?
I've found a way to exclude all properties that match a given type, thanks to this article: https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c
I made a few adaptations, but here is the details:
// 1 Transform the type to flag all the undesired keys as 'never'
type FlagExcludedType<Base, Type> = { [Key in keyof Base]: Base[Key] extends Type ? never : Key };
// 2 Get the keys that are not flagged as 'never'
type AllowedNames<Base, Type> = FlagExcludedType<Base, Type>[keyof Base];
// 3 Use this with a simple Pick to get the right interface, excluding the undesired type
type OmitType<Base, Type> = Pick<Base, AllowedNames<Base, Type>>;
// 4 Exclude the Function type to only get properties
type ConstructorType<T> = OmitType<T, Function>;
Try It
There might be a simpler way, I've tried playing with ConstructorParameters
and defining a constructor signature but without results.
Update
Found an equivalent while browsing the typescript documentation here: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types
type NonFunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;
It's a bit less verbose since the omitted type is not generic, but it's the same idea.
While reading this issue, I found someone posting this succinct type
type ExcludeMethods<T> =
Pick<T, { [K in keyof T]: T[K] extends (_: any) => any ? never : K }[keyof T]>;
Note that this type does not remove getters and setters.
Edit: Or even shorter
type ExcludeMethods<T> =
Pick<T, { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]>;