import { Schema as S } from "@effect/schema" import { AbstractConstructor, Simplify } from "type-fest" import { Trait, TraitTuple } from "../Trait" import { StaticImplements, TraitExpressionLike } from "../TraitExpression" import { Extend, StaticMembers } from "../util" export class EffectSchemaTraitExpression< Fields extends S.Struct.Fields, I, R, C, Inherited extends object, Proto, Static extends object, const Traits extends readonly Trait[], const Mutability extends "Immutable" | "Mutable", const EncodedMutability extends "Immutable" | "Mutable", > implements TraitExpressionLike< S.Class, Traits > { constructor( readonly superclass: S.Class, readonly superclassStatic: Static, readonly traits: Traits, readonly mutability: Mutability, readonly encodedMutability: EncodedMutability, ) {} extends(): ( AbstractConstructor< Simplify< ApplyMutability, Mutability> & Extend<[ Omit, ...TraitTuple.MapImplInstance ]> & Proto >, ConstructorParameters> > & StaticMembers< S.Class< Self, Fields, ApplyMutability, R, C, Inherited, Proto > > & Simplify< Extend<[ Static, ...TraitTuple.MapImplStaticMembers ]> > ) { return this.traits.reduce( (previous, trait) => trait.apply(previous), this.superclass, ) as any } staticImplements(_target: StaticImplements, _context: any) {} get staticImplementsStage2() { return (_target: StaticImplements) => {} } } type ApplyMutability = ( Mutability extends "Immutable" ? { +readonly [P in keyof T]: T[P] } : { -readonly [P in keyof T]: T[P] } )