Working expresses

This commit is contained in:
Julien Valverdé
2024-02-01 03:41:18 +01:00
parent a82c978c9e
commit 288969a789
3 changed files with 72 additions and 55 deletions

View File

@@ -1,7 +1,7 @@
import { Call, Pipe, Tuples } from "hotscript" import { Call, ComposeLeft, Pipe, Tuples } from "hotscript"
import { AbstractClass, Opaque } from "type-fest" import { AbstractClass, Opaque } from "type-fest"
import { Trait, TraitAbstractMembersFn, TraitApplierSuperTag, TraitClassFn, TraitImplClassFn, TraitImplInstanceFn, TraitInstanceFn } from "." import { Trait, TraitAbstractMembersFn, TraitApplierSuperTag, TraitImplClassFn, TraitImplInstanceFn } from "."
import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" import { ExtendFn, ExtendableFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util"
class TraitExpression< 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>> = ( export type Implements<Exp extends TraitExpression<any, any>> = (
Exp extends TraitExpression<any, infer Traits> Exp extends TraitExpression<any, infer Traits>
? Pipe<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< export function extendsAndExpresses<
Super extends AbstractClass<any>, Super extends AbstractClass<any>,
Traits extends readonly Trait<any, any>[], Traits extends readonly Trait<any, any>[],
>( >(
superclass: Super, superclass: Super,
...traits: Traits ...traits: Traits
) { ): ExtendsAndExpressesReturnType<Super, Traits> {
return new TraitExpression(superclass, traits) return new TraitExpression(superclass, traits) as any
} }
class DefaultSuperclass {} class DefaultSuperclass {}
@@ -96,6 +118,6 @@ export function expresses<
Traits extends readonly Trait<any, any>[], Traits extends readonly Trait<any, any>[],
>( >(
...traits: Traits ...traits: Traits
) { ): ExtendsAndExpressesReturnType<typeof DefaultSuperclass, Traits> {
return new TraitExpression(DefaultSuperclass, traits) return new TraitExpression(DefaultSuperclass, traits) as any
} }

View File

@@ -1,6 +1,4 @@
import { Booleans, Call, Compose, ComposeLeft, Match, Pipe, Tuples } from "hotscript" import { Implements, TraitAbstractMembers, extendsAndExpresses, trait } from "."
import { Implements, TraitAbstractMembers, TraitAbstractMembersFn, expresses, extendsAndExpresses, trait } from "."
import { CheckExtendableFn, ExtendFn, Extendable, ExtendableFn, SimplifyFn } from "./util"
const PrintsHelloOnNew = trait()(Super => const PrintsHelloOnNew = trait()(Super =>
@@ -45,7 +43,8 @@ const ActiveStatefulSubscription = trait<ActiveStatefulSubscriptionAbstractMembe
class TestSuperclass { class TestSuperclass {
id: number = 69 // id: number = 69
static test = 69
} }
@@ -54,11 +53,7 @@ const exp = extendsAndExpresses(
Identifiable<bigint>(), Identifiable<bigint>(),
// Identifiable<number>() // Identifiable<number>()
) )
type ExpImpl = Implements<typeof exp> // type ExpImpl = ImplStaticMembersExtendable<typeof TestSuperclass, typeof exp.traits>
type ExpAbstractMembers = Pipe<typeof exp.traits, [
Tuples.Map<TraitAbstractMembersFn>,
]>
type ExpExtendable = Extendable<ExpAbstractMembers>
class User extends exp.extends() implements Implements<typeof exp> { class User extends exp.extends() implements Implements<typeof exp> {
id: bigint = -1n id: bigint = -1n

View File

@@ -3,16 +3,16 @@ import { AbstractClass, Class, Opaque } from "type-fest"
import { StaticMembers } from "./util" import { StaticMembers } from "./util"
type AddAbstractMembersToImpl< // type AddAbstractMembersToImpl<
Impl extends Class<object, []>, // Impl extends Class<object, []>,
AbstractMembers extends object, // AbstractMembers extends object,
> = ( // > = (
Class< // Class<
InstanceType<Impl> & AbstractMembers, // InstanceType<Impl> & AbstractMembers,
ConstructorParameters<Impl> // ConstructorParameters<Impl>
> & // > &
StaticMembers<Impl> // StaticMembers<Impl>
) // )
type RemoveAbstractMembersFromImplInstance< type RemoveAbstractMembersFromImplInstance<
ImplInstanceWithAbstractMembers extends AbstractMembers, ImplInstanceWithAbstractMembers extends AbstractMembers,
@@ -21,7 +21,7 @@ type RemoveAbstractMembersFromImplInstance<
Omit<ImplInstanceWithAbstractMembers, keyof AbstractMembers> Omit<ImplInstanceWithAbstractMembers, keyof AbstractMembers>
) )
type RemoveAbstractMembersFromImpl< type RemoveAbstractMembersFromImplClass<
ImplWithAbstractMembers extends Class<AbstractMembers, []>, ImplWithAbstractMembers extends Class<AbstractMembers, []>,
AbstractMembers extends object, AbstractMembers extends object,
> = ( > = (
@@ -63,7 +63,7 @@ export interface TraitAbstractMembersFn extends Fn {
export type TraitImplClass<T> = ( export type TraitImplClass<T> = (
T extends Trait<infer AbstractMembers, infer ImplWithAbstractMembers> T extends Trait<infer AbstractMembers, infer ImplWithAbstractMembers>
? RemoveAbstractMembersFromImpl< ? RemoveAbstractMembersFromImplClass<
ImplWithAbstractMembers, ImplWithAbstractMembers,
AbstractMembers AbstractMembers
> >