import { Constructor } from '@loopback/context'; /** * A replacement for `typeof Target` to be used in mixin class definitions. * This is a workaround for TypeScript limitation described in * - https://github.com/microsoft/TypeScript/issues/17293 * - https://github.com/microsoft/TypeScript/issues/17744 * - https://github.com/microsoft/TypeScript/issues/36060 * * @example * * ```ts * export function MyMixin>(superClass: T) { * return class extends superClass { * // contribute new class members * } * }; * ``` * * TypeScript does not allow class mixins to access protected members from * the base class. You can use the following approach as a workaround: * * ```ts * // eslint-disable-next-line @typescript-eslint/ban-ts-comment * // @ts-ignore * (this as unknown as {YourBaseClass}).protectedMember * ``` * * The directive `@ts-ignore` suppresses compiler error about accessing * a protected member from outside. Unfortunately, it also disables other * compile-time checks (e.g. to verify that a protected method was invoked * with correct arguments, and so on). This is the same behavior you * would get by using `Constructor` instead of `MixinTarget`. * The major improvement is that TypeScript can still infer the return * type of the protected member, therefore `any` is NOT introduced to subsequent * code. * * TypeScript also does not allow mixin class to overwrite a method inherited * from a mapped type, see https://github.com/microsoft/TypeScript/issues/38496 * As a workaround, use `@ts-ignore` to disable the error. * * ```ts * export function RepositoryMixin>( * superClass: T, * ) { * return class extends superClass { * // @ts-ignore * public component( * componentCtor: Constructor, * nameOrOptions?: string | BindingFromClassOptions, * ) { * const binding = super.component(componentCtor, nameOrOptions); * // ... * return binding; * } * } * ``` */ export type MixinTarget = Constructor<{ [P in keyof T]: T[P]; }>;