0.1.0 #1
@@ -1,7 +1,7 @@
|
||||
import { Call, Pipe, Tuples } from "hotscript"
|
||||
import { Call, ComposeLeft, Pipe, Tuples } from "hotscript"
|
||||
import { AbstractClass, Opaque } from "type-fest"
|
||||
import { Trait, TraitAbstractMembersFn, TraitApplierSuperTag, TraitClassFn, TraitImplClassFn, TraitImplInstanceFn, TraitInstanceFn } from "."
|
||||
import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util"
|
||||
import { Trait, TraitAbstractMembersFn, TraitApplierSuperTag, TraitImplClassFn, TraitImplInstanceFn } from "."
|
||||
import { ExtendFn, ExtendableFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util"
|
||||
|
||||
|
||||
class TraitExpression<
|
||||
@@ -42,33 +42,6 @@ class TraitExpression<
|
||||
}
|
||||
}
|
||||
|
||||
type TraitExpressionOutput<Exp extends TraitExpression<any, any>> = (
|
||||
Exp extends TraitExpression<infer Super, infer Traits>
|
||||
? (
|
||||
AbstractClass<
|
||||
Pipe<[
|
||||
InstanceType<Super>,
|
||||
...Call<Tuples.Map<TraitInstanceFn>, Traits>,
|
||||
], [
|
||||
ExtendFn,
|
||||
SimplifyFn,
|
||||
]>,
|
||||
|
||||
ConstructorParameters<Super>
|
||||
> &
|
||||
|
||||
Pipe<[
|
||||
Super,
|
||||
...Call<Tuples.Map<TraitClassFn>, Traits>,
|
||||
], [
|
||||
Tuples.Map<StaticMembersFn>,
|
||||
ExtendFn,
|
||||
SimplifyFn,
|
||||
]>
|
||||
)
|
||||
: never
|
||||
)
|
||||
|
||||
export type Implements<Exp extends TraitExpression<any, any>> = (
|
||||
Exp extends TraitExpression<any, infer Traits>
|
||||
? Pipe<Traits, [
|
||||
@@ -80,14 +53,63 @@ export type Implements<Exp extends TraitExpression<any, any>> = (
|
||||
)
|
||||
|
||||
|
||||
type AbstractMembersExtendable<
|
||||
Super extends AbstractClass<any>,
|
||||
Traits extends readonly Trait<any, any>[],
|
||||
> = (
|
||||
Call<ExtendableFn, [
|
||||
InstanceType<Super>,
|
||||
...Call<Tuples.Map<TraitAbstractMembersFn>, Traits>,
|
||||
]>
|
||||
)
|
||||
|
||||
type ImplInstanceExtendable<
|
||||
Super extends AbstractClass<any>,
|
||||
Traits extends readonly Trait<any, any>[],
|
||||
> = (
|
||||
Call<ExtendableFn, [
|
||||
InstanceType<Super>,
|
||||
...Call<Tuples.Map<TraitImplInstanceFn>, Traits>,
|
||||
]>
|
||||
)
|
||||
|
||||
type ImplStaticMembersExtendable<
|
||||
Super extends AbstractClass<any>,
|
||||
Traits extends readonly Trait<any, any>[],
|
||||
> = (
|
||||
Call<ExtendableFn, [
|
||||
StaticMembers<Super>,
|
||||
...Call<
|
||||
Tuples.Map<
|
||||
ComposeLeft<[TraitImplClassFn, StaticMembersFn]>
|
||||
>,
|
||||
Traits
|
||||
>,
|
||||
]>
|
||||
)
|
||||
|
||||
|
||||
type ExtendsAndExpressesReturnType<
|
||||
Super extends AbstractClass<any>,
|
||||
Traits extends readonly Trait<any, any>[],
|
||||
> = (
|
||||
AbstractMembersExtendable<Super, Traits> extends true ?
|
||||
ImplInstanceExtendable<Super, Traits> extends true ?
|
||||
ImplStaticMembersExtendable<Super, Traits> extends true ?
|
||||
TraitExpression<Super, Traits>
|
||||
: "Type conflict between the traits implementation static members and/or the superclass static members."
|
||||
: "Type conflict between the traits implementation instances and/or the superclass instance."
|
||||
: "Type conflict between the traits abstract members and/or the superclass instance."
|
||||
)
|
||||
|
||||
export function extendsAndExpresses<
|
||||
Super extends AbstractClass<any>,
|
||||
Traits extends readonly Trait<any, any>[],
|
||||
>(
|
||||
superclass: Super,
|
||||
...traits: Traits
|
||||
) {
|
||||
return new TraitExpression(superclass, traits)
|
||||
): ExtendsAndExpressesReturnType<Super, Traits> {
|
||||
return new TraitExpression(superclass, traits) as any
|
||||
}
|
||||
|
||||
class DefaultSuperclass {}
|
||||
@@ -96,6 +118,6 @@ export function expresses<
|
||||
Traits extends readonly Trait<any, any>[],
|
||||
>(
|
||||
...traits: Traits
|
||||
) {
|
||||
return new TraitExpression(DefaultSuperclass, traits)
|
||||
): ExtendsAndExpressesReturnType<typeof DefaultSuperclass, Traits> {
|
||||
return new TraitExpression(DefaultSuperclass, traits) as any
|
||||
}
|
||||
|
||||
13
src/tests.ts
13
src/tests.ts
@@ -1,6 +1,4 @@
|
||||
import { Booleans, Call, Compose, ComposeLeft, Match, Pipe, Tuples } from "hotscript"
|
||||
import { Implements, TraitAbstractMembers, TraitAbstractMembersFn, expresses, extendsAndExpresses, trait } from "."
|
||||
import { CheckExtendableFn, ExtendFn, Extendable, ExtendableFn, SimplifyFn } from "./util"
|
||||
import { Implements, TraitAbstractMembers, extendsAndExpresses, trait } from "."
|
||||
|
||||
|
||||
const PrintsHelloOnNew = trait()(Super =>
|
||||
@@ -45,7 +43,8 @@ const ActiveStatefulSubscription = trait<ActiveStatefulSubscriptionAbstractMembe
|
||||
|
||||
|
||||
class TestSuperclass {
|
||||
id: number = 69
|
||||
// id: number = 69
|
||||
static test = 69
|
||||
}
|
||||
|
||||
|
||||
@@ -54,11 +53,7 @@ const exp = extendsAndExpresses(
|
||||
Identifiable<bigint>(),
|
||||
// Identifiable<number>()
|
||||
)
|
||||
type ExpImpl = Implements<typeof exp>
|
||||
type ExpAbstractMembers = Pipe<typeof exp.traits, [
|
||||
Tuples.Map<TraitAbstractMembersFn>,
|
||||
]>
|
||||
type ExpExtendable = Extendable<ExpAbstractMembers>
|
||||
// type ExpImpl = ImplStaticMembersExtendable<typeof TestSuperclass, typeof exp.traits>
|
||||
|
||||
class User extends exp.extends() implements Implements<typeof exp> {
|
||||
id: bigint = -1n
|
||||
|
||||
24
src/trait.ts
24
src/trait.ts
@@ -3,16 +3,16 @@ import { AbstractClass, Class, Opaque } from "type-fest"
|
||||
import { StaticMembers } from "./util"
|
||||
|
||||
|
||||
type AddAbstractMembersToImpl<
|
||||
Impl extends Class<object, []>,
|
||||
AbstractMembers extends object,
|
||||
> = (
|
||||
Class<
|
||||
InstanceType<Impl> & AbstractMembers,
|
||||
ConstructorParameters<Impl>
|
||||
> &
|
||||
StaticMembers<Impl>
|
||||
)
|
||||
// type AddAbstractMembersToImpl<
|
||||
// Impl extends Class<object, []>,
|
||||
// AbstractMembers extends object,
|
||||
// > = (
|
||||
// Class<
|
||||
// InstanceType<Impl> & AbstractMembers,
|
||||
// ConstructorParameters<Impl>
|
||||
// > &
|
||||
// StaticMembers<Impl>
|
||||
// )
|
||||
|
||||
type RemoveAbstractMembersFromImplInstance<
|
||||
ImplInstanceWithAbstractMembers extends AbstractMembers,
|
||||
@@ -21,7 +21,7 @@ type RemoveAbstractMembersFromImplInstance<
|
||||
Omit<ImplInstanceWithAbstractMembers, keyof AbstractMembers>
|
||||
)
|
||||
|
||||
type RemoveAbstractMembersFromImpl<
|
||||
type RemoveAbstractMembersFromImplClass<
|
||||
ImplWithAbstractMembers extends Class<AbstractMembers, []>,
|
||||
AbstractMembers extends object,
|
||||
> = (
|
||||
@@ -63,7 +63,7 @@ export interface TraitAbstractMembersFn extends Fn {
|
||||
|
||||
export type TraitImplClass<T> = (
|
||||
T extends Trait<infer AbstractMembers, infer ImplWithAbstractMembers>
|
||||
? RemoveAbstractMembersFromImpl<
|
||||
? RemoveAbstractMembersFromImplClass<
|
||||
ImplWithAbstractMembers,
|
||||
AbstractMembers
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user