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(
new TraitExpression(DefaultSuperclass, [] as const)
new TraitExpression(NullTraitExpressionSuperclass, [] as const)
)

View File

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