Trait refactoring
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Julien Valverdé
2024-02-04 00:26:09 +01:00
parent 8d29d9ba94
commit 0ff6b7896e
3 changed files with 46 additions and 69 deletions

View File

@@ -156,8 +156,8 @@ type GetTraitExpression<
) )
class DefaultSuperclass {} export class NullTraitExpressionSuperclass {}
export const expression = new TraitExpressionBuilder( export const expression = new TraitExpressionBuilder(
new TraitExpression(DefaultSuperclass, [] as const) new TraitExpression(NullTraitExpressionSuperclass, [] as const)
) )

View File

@@ -1,3 +1,3 @@
export * from "./TraitExpression"
export * from "./abstract" export * from "./abstract"
export * from "./expresses"
export * from "./trait" export * from "./trait"

View File

@@ -1,119 +1,96 @@
import { Fn } from "hotscript" import { Call, Fn } from "hotscript"
import { AbstractClass, Class, Opaque } from "type-fest" import { AbstractClass, Class, Opaque } from "type-fest"
import { AbstractTag, TraitExpression } from "." import { AbstractTag, NullTraitExpressionSuperclass, TraitExpression } from "."
import { StaticMembers } from "./util" import { StaticMembers } from "./util"
type AddAbstractToImpl< type AddAbstractToImplClass<
Impl extends Class<{}, []>, ImplClass extends Class<{}, []>,
Abstract extends {}, Abstract extends {},
> = ( > = (
Class< Class<
InstanceType<Impl> & Abstract, InstanceType<ImplClass> & Abstract,
ConstructorParameters<Impl> ConstructorParameters<ImplClass>
> & > &
StaticMembers<Impl> StaticMembers<ImplClass>
) )
type RemoveAbstractFromImpl< type RemoveAbstractFromImplClass<
ImplWithAbstract extends Class<Abstract, []>, ImplClassWithAbstract extends Class<Abstract, []>,
Abstract extends {}, Abstract extends {},
> = ( > = (
Class< Class<
Omit<InstanceType<ImplWithAbstract>, keyof Abstract>, Omit<InstanceType<ImplClassWithAbstract>, keyof Abstract>,
ConstructorParameters<ImplWithAbstract> ConstructorParameters<ImplClassWithAbstract>
> & > &
StaticMembers<ImplWithAbstract> StaticMembers<ImplClassWithAbstract>
) )
export class Trait< export class Trait<
Super extends TraitExpression<any, any>[], Super extends TraitExpression<typeof NullTraitExpressionSuperclass, any>[],
Abstract extends {}, Abstract extends {},
Impl extends Class<{}, []>, ImplClass extends Class<{}, []>,
> { > {
constructor( constructor(
readonly supertraits: Super, readonly superExpression: Super,
readonly ownAbstract: Abstract, readonly abstract: Abstract,
readonly apply: (Super: AbstractClass<{}>) => Impl, readonly apply: (Super: AbstractClass<{}>) => ImplClass,
) {} ) {}
} }
export interface Trait< export interface TraitOwnAbstractFn extends Fn {
Super extends TraitExpression<any, any>[], return: this["arg0"] extends Trait<any, infer Abstract, any>
Abstract extends {}, ? Abstract
Impl extends Class<{}, []>,
> {
get ownImplClass(): Impl
}
export type TraitAbstractMembers<T> = (
T extends Trait<infer AbstractMembers, any, any>
? AbstractMembers
: never : never
)
export interface TraitAbstractMembersFn extends Fn {
return: TraitAbstractMembers<this["arg0"]>
} }
export type TraitOwnAbstract<T> = Call<TraitOwnAbstractFn, T>
export type TraitImplClass<T> = ( export interface TraitOwnImplClassFn extends Fn {
T extends Trait<any, infer Impl, any> return: this["arg0"] extends Trait<any, any, infer ImplClass>
? Impl ? ImplClass
: never : never
)
export interface TraitImplClassFn extends Fn {
return: TraitImplClass<this["arg0"]>
} }
export type TraitOwnImplClass<T> = Call<TraitOwnImplClassFn, T>
export type TraitImplInstance<T> = ( export interface TraitOwnImplInstanceFn extends Fn {
T extends Trait<any, infer Impl> return: this["arg0"] extends Trait<any, infer Abstract, infer ImplClass>
? InstanceType<Impl> ? InstanceType<ImplClass>
: never : never
)
export interface TraitImplInstanceFn extends Fn {
return: TraitImplInstance<this["arg0"]>
} }
export type TraitOwnImplInstance<T> = Call<TraitOwnImplInstanceFn, T>
export type TraitClass<T> = ( export interface TraitOwnClassFn extends Fn {
T extends Trait<infer Abstract, infer Impl> return: this["arg0"] extends Trait<any, infer Abstract, infer ImplClass>
? AddAbstractToImpl<Impl, Abstract> ? AddAbstractToImplClass<ImplClass, Abstract>
: never : never
)
export interface TraitClassFn extends Fn {
return: TraitClass<this["arg0"]>
} }
export type TraitOwnClass<T> = Call<TraitOwnClassFn, T>
export type TraitInstance<T> = ( export interface TraitOwnInstanceFn extends Fn {
T extends Trait<infer Abstract, infer Impl> return: this["arg0"] extends Trait<any, infer Abstract, infer ImplClass>
? InstanceType< ? InstanceType<
AddAbstractToImpl<Impl, Abstract> AddAbstractToImplClass<ImplClass, Abstract>
> >
: never : never
)
export interface TraitInstanceFn extends Fn {
return: TraitInstance<this["arg0"]>
} }
export type TraitOwnInstance<T> = Call<TraitOwnInstanceFn, T>
export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper" export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper"
export function trait< export function trait<
Abstract extends {}, Abstract extends {},
ImplWithAbstract extends Class<Abstract, []>, ImplClassWithAbstract extends Class<Abstract, []>,
>( >(
abstract: Opaque<Abstract, AbstractTag>, abstract: Opaque<Abstract, AbstractTag>,
apply: (Super: Opaque<AbstractClass<Abstract>, TraitApplierSuperTag>) => ( apply: (Super: Opaque<AbstractClass<Abstract>, TraitApplierSuperTag>) => (
Opaque<ImplWithAbstract, TraitApplierSuperTag> Opaque<ImplClassWithAbstract, TraitApplierSuperTag>
), ),
) { ) {
return new Trait( return new Trait(
[] as const, [] as const,
abstract as Abstract, abstract as Abstract,
apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImpl<ImplWithAbstract, Abstract>, apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass<ImplClassWithAbstract, Abstract>,
) )
} }