1// Utility types:
2
3type GetProps<TBase> = TBase extends new (props: infer P) => any ? P : never
4type GetInstance<TBase> = TBase extends new (...args: any[]) => infer I ? I : never
5type MergeCtor<A, B> = new (props: GetProps<A> & GetProps<B>) => GetInstance<A> & GetInstance<B>
6
7
8// Usage:
9// bypass the restriction and manually type the signature
10function GeometryMixin<TBase extends MixinBase>(Base: TBase) {
11 // key 1: assert Base as any to mute the TS error
12 const Derived = class Geometry extends (Base as any) {
13 shape: 'rectangle' | 'triangle'
14 constructor(props: { shape: 'rectangle' | 'triangle' }) {
15 super(props)
16 this.shape = props.shape
17 }
18 }
19
20 // key 2: manually cast type to be MergeCtor
21 return Derived as MergeCtor<typeof Derived, TBase>
22}
23