import { AbstractClass, Class, Simplify } from "type-fest" import { Trait, TraitTuple } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { Extend, StaticMembers } from "./util" export class TraitExpression< Superclass extends AbstractClass, const Traits extends Trait[], > { constructor( readonly superclass: Superclass, readonly traits: Traits, ) {} get extends(): ( AbstractClass< Simplify< Extend<[ InstanceType, ...TraitTuple.MapImplInstance, ]> >, ConstructorParameters > & Simplify< Extend<[ StaticMembers, ...TraitTuple.MapImplStaticMembers, ]> > ) { return this.traits.reduce( (previous, trait) => trait.apply(previous), this.superclass, ) as any } implementsStatic(target: ImplementsStatic, context: any) {} subtrait< This extends TraitExpression >( this: This ) { return new TraitBuilder< This, Simplify< Extend> >, Simplify< Extend> >, AbstractClass< Simplify< Extend> > > & Simplify< Extend> > >( this, {} as any, {} as any, Super => class extends Super {} as any, ) } } export namespace TraitExpression { export class NullSuperclass { static readonly _tag = "@thilawyn/traitify-ts/TraitExpression.NullSuperclass" constructor(...args: any[]) {} } export type Superclass = ( T extends TraitExpression ? Superclass : never ) export type Traits = ( T extends TraitExpression ? Traits : never ) } export type Implements< Exp extends TraitExpression[]> > = ( Simplify< Extend< TraitTuple.MapAbstract< TraitExpression.Traits > > > ) export type ImplementsStatic< Exp extends TraitExpression[]> > = ( Simplify< Extend< TraitTuple.MapStaticAbstract< TraitExpression.Traits > > > ) export type TraitExpressionClass< Exp extends TraitExpression[]> > = ( AbstractClass< TraitExpressionInstance, ConstructorParameters> > & TraitExpressionStaticMembers ) export type TraitExpressionConcreteClass< Exp extends TraitExpression[]> > = ( Class< TraitExpressionInstance, ConstructorParameters> > & TraitExpressionStaticMembers ) export type TraitExpressionInstance< Exp extends TraitExpression[]> > = ( Simplify< Extend<[ InstanceType>, ...TraitTuple.MapInstance>, ]> > ) export type TraitExpressionStaticMembers< Exp extends TraitExpression[]> > = ( Simplify< Extend<[ StaticMembers>, ...TraitTuple.MapStaticMembers>, ]> > )