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