import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" import { Extend, StaticMembers } from "./util" export class Trait< SuperExpression extends TraitExpression< typeof TraitExpression.NullSuperclass, readonly Trait[] >, Abstract extends object, StaticAbstract extends object, ImplClass extends AbstractClass, > { constructor( readonly superExpression: SuperExpression, readonly abstract: Abstract, readonly staticAbstract: StaticAbstract, readonly apply: (Super: AbstractClass) => ImplClass, ) {} } export namespace Trait { export type SuperExpression = ( T extends Trait ? SuperExpression : never ) export type Supertraits = ( TraitExpression.Traits> ) export type Abstract = ( T extends Trait ? Abstract : never ) export type StaticAbstract = ( T extends Trait ? StaticAbstract : never ) export type ImplClass = ( T extends Trait ? ImplClass : never ) export type ImplInstance = ( InstanceType> ) export type ImplStaticMembers = ( StaticMembers> ) export type Instance = ( Extend<[ Trait.Abstract, Trait.ImplInstance, ]> ) export type Static = ( Extend<[ Trait.StaticAbstract, Trait.ImplStaticMembers, ]> ) } export namespace TraitTuple { export type MapAbstract = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.Abstract } export type MapStaticAbstract = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.StaticAbstract } export type MapImplClass = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.ImplClass } export type MapImplInstance = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.ImplInstance } export type MapImplStaticMembers = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.ImplStaticMembers } export type MapInstance = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.Instance } export type MapStaticMembers = { [K in keyof T]: K extends keyof [] ? T[K] : Trait.Static } } export type TraitClass> = ( AbstractClass, any[]> & TraitStaticMembers ) export type TraitConcreteClass> = ( Class, any[]> & TraitStaticMembers ) export type TraitInstance> = ( Simplify> ) export type TraitStaticMembers> = ( Simplify> )