import type { array } from "./arrays.ts"; import type { conform, satisfy, show } from "./generics.ts"; import type { intersectParameters } from "./intersections.ts"; import { type Constructor } from "./objectKinds.ts"; import { NoopBase } from "./records.ts"; export type TraitImplementation = , s extends CompositionState = composeTraits<[ ...traits, implementation ], "implementation">, cls extends TraitConstructor = TraitConstructor>(...args: [...traits, implementation & ThisType>]) => cls; export type TraitComposition = >(...traits: conform) => TraitConstructor; export declare const hasTrait: (traitClass: Constructor) => (o: unknown) => boolean; export type TraitDeclaration = { abstractMethods?: object; abstractProps?: object; abstractStatics?: object; dynamicBase?: object; }; /** @ts-ignore required to extend NoopBase */ export declare abstract class Trait extends NoopBase { abstractMethods: abstractMethods; abstractProps: abstractProps; abstractStatic: abstractStatics; static get [Symbol.hasInstance](): (o: unknown) => boolean; traitsOf(): readonly TraitConstructor[]; } export declare const compose: TraitComposition; export declare const implement: TraitImplementation; export type TraitConstructor = statics & (new (...args: params) => Trait<{ abstractMethods: abstractMethods; abstractProps: abstractProps; abstractStatics: abstractStatics; }> & instance); type CompositionState = { validated: array; remaining: array; params: array; kind: TraitCompositionKind; implemented: object; abstractMethods: object; abstractProps: object; abstractStatics: object; statics: object; }; export type TraitCompositionKind = "abstract" | "implementation"; export type composeTraits = _compose<{ validated: []; remaining: traits; kind: kind; params: []; implemented: {}; abstractMethods: {}; abstractProps: {}; abstractStatics: {}; statics: {}; }>; type intersectImplementations = { [k in keyof l]: k extends keyof r ? l[k] extends (...args: infer lArgs) => infer lReturn ? r[k] extends (...args: infer rArgs) => infer rReturn ? (...args: intersectParameters) => lReturn & rReturn : l[k] & r[k] : l[k] & r[k] : l[k]; } & Omit; type _compose = s["remaining"] extends (readonly [ TraitConstructor, ...infer tail ]) ? _compose<{ validated: [...s["validated"], s["remaining"][0]]; remaining: tail; kind: s["kind"]; params: intersectParameters; implemented: intersectImplementations>; statics: intersectImplementations>; abstractMethods: intersectImplementations; abstractProps: intersectImplementations; abstractStatics: intersectImplementations; }> : finalizeState; type finalizeState = satisfy; statics: show>; abstractMethods: show>; abstractProps: show>; abstractStatics: show>; }>; export type implementationOf = s["abstractMethods"] & ({} extends s["abstractProps"] ? {} : { construct: (...args: s["params"]) => s["abstractProps"]; }) & ({} extends s["abstractStatics"] ? {} : { statics: s["abstractStatics"]; }); export {};