0.1.0 #1
@@ -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)
|
||||||
)
|
)
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
|
export * from "./TraitExpression"
|
||||||
export * from "./abstract"
|
export * from "./abstract"
|
||||||
export * from "./expresses"
|
|
||||||
export * from "./trait"
|
export * from "./trait"
|
||||||
|
|||||||
103
src/trait.ts
103
src/trait.ts
@@ -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>,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user