Moved old code to legacy/
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Julien Valverdé
2023-12-28 19:25:19 +01:00
parent 300b52e31c
commit d759b2cbba
7 changed files with 196 additions and 197 deletions

View File

@@ -1 +1,81 @@
export * from "./trait"
import { AbstractClass, AbstractConstructor, Opaque, UnionToIntersection } from "type-fest"
/**
* Represents the static members of a class.
*
* @template C - The type of the class for which static members are extracted.
* @typeparam The static members of the class.
*/
export type StaticMembers<C> = Pick<C, keyof C>
export type Trait<
C extends AbstractClass<any>
> = Opaque<
TraitApplier<C>,
"thilatrait/Trait"
>
export type TraitApplier<
C extends AbstractClass<any>
> =
(Parent: AbstractConstructor<any>) => C
export type UnwrapTraitC<T> =
T extends Trait<infer C>
? C
: never
export function trait<
C extends AbstractClass<any>
>(
applier: TraitApplier<C>
) {
return applier as Trait<C>
}
export function extendsAndExpresses<
C extends AbstractClass<any>,
Traits extends readonly Trait<any>[],
>(
extend: C,
traits: Traits,
) {
return traits.reduce(
(previous, trait) => trait(previous),
extend,
) as (
AbstractClass<
InstanceType<C> &
UnionToIntersection<
InstanceType<
UnwrapTraitC<
Traits[number]
>
>
>,
ConstructorParameters<C>
> &
StaticMembers<C> &
StaticMembers<
UnionToIntersection<
UnwrapTraitC<
Traits[number]
>
>
>
)
}
export function expresses<
Traits extends readonly Trait<any>[],
>(
...traits: Traits
) {
return extendsAndExpresses(Object, traits)
}

74
src/legacy/tests.ts Normal file
View File

@@ -0,0 +1,74 @@
import { AbstractClass } from "type-fest"
import { expresses } from "./trait"
function inspectClass(class_: AbstractClass<any, any>) {
Object.getOwnPropertyNames(class_).forEach(name => {
console.log(
"[static]",
name,
Object.getOwnPropertyDescriptor(class_, name)
)
})
Object.getOwnPropertyNames(class_.prototype).forEach(name => {
console.log(
"[prototype]",
name,
Object.getOwnPropertyDescriptor(class_.prototype, name)
)
})
}
abstract class Identified<ID> {
abstract id: ID
equals(el: Identified<ID>) {
return this.id === el.id
}
// initializer() {
// console.log("Identified initializer")
// }
}
class ImplementsIdentifiable<ID> extends Identified<ID> {
id!: ID
}
abstract class Permissible {
static readonly defaultPermissions: string[] = []
permissions: string[] = []
// permissions!: string[]
constructor() {
console.log("Permissible constructor")
}
initializer() {
console.log("Permissible initializer")
this.permissions = []
}
}
class User extends expresses(
Identified as typeof Identified<bigint>,
// Identified<string>,
Permissible,
) {
readonly id: bigint
constructor(id: bigint) {
super()
this.id = id
}
}
const user1 = new User(BigInt(1))
const user2 = new User(BigInt(2))
console.log(user1)
console.log(user1.equals(user2))

View File

@@ -1,62 +0,0 @@
import { expresses, trait } from "./trait-inheritance"
const Identifiable = <ID>() =>
trait(Parent => {
abstract class Identified extends Parent {
abstract id: ID
equals(el: Identified) {
return this.id === el.id
}
constructor(...args: any[]) {
super(...args)
console.log("Identified constructor")
}
}
return Identified
})
const ImplementsIdentifiable = <ID>(defaultID: ID) =>
trait(Parent => {
abstract class ImplementsIdentifiable extends Identifiable<ID>()(Parent) {
id: ID = defaultID
}
return ImplementsIdentifiable
})
const Permissible = trait(Parent => {
abstract class Permissible extends Parent {
static readonly defaultPermissions: string[] = []
permissions: string[] = []
constructor(...args: any[]) {
super(...args)
console.log("Permissible constructor")
}
}
return Permissible
})
const UserProto = expresses(
// Identifiable<bigint>(),
ImplementsIdentifiable(0n),
Permissible,
)
class User extends UserProto {
constructor(id: bigint) {
super()
this.id = id
}
}
const user1 = new User(1n)
console.log(user1)
console.log(user1.equals(user1))

View File

@@ -1,74 +1,62 @@
import { AbstractClass } from "type-fest"
import { expresses } from "./trait"
import { expresses, trait } from "."
function inspectClass(class_: AbstractClass<any, any>) {
Object.getOwnPropertyNames(class_).forEach(name => {
console.log(
"[static]",
name,
Object.getOwnPropertyDescriptor(class_, name)
)
})
Object.getOwnPropertyNames(class_.prototype).forEach(name => {
console.log(
"[prototype]",
name,
Object.getOwnPropertyDescriptor(class_.prototype, name)
)
})
}
abstract class Identified<ID> {
const Identifiable = <ID>() =>
trait(Parent => {
abstract class Identified extends Parent {
abstract id: ID
equals(el: Identified<ID>) {
equals(el: Identified) {
return this.id === el.id
}
// initializer() {
// console.log("Identified initializer")
// }
constructor(...args: any[]) {
super(...args)
console.log("Identified constructor")
}
}
class ImplementsIdentifiable<ID> extends Identified<ID> {
id!: ID
return Identified
})
const ImplementsIdentifiable = <ID>(defaultID: ID) =>
trait(Parent => {
abstract class ImplementsIdentifiable extends Identifiable<ID>()(Parent) {
id: ID = defaultID
}
return ImplementsIdentifiable
})
abstract class Permissible {
const Permissible = trait(Parent => {
abstract class Permissible extends Parent {
static readonly defaultPermissions: string[] = []
permissions: string[] = []
// permissions!: string[]
constructor() {
constructor(...args: any[]) {
super(...args)
console.log("Permissible constructor")
}
initializer() {
console.log("Permissible initializer")
this.permissions = []
}
}
return Permissible
})
class User extends expresses(
Identified as typeof Identified<bigint>,
// Identified<string>,
const UserProto = expresses(
// Identifiable<bigint>(),
ImplementsIdentifiable(0n),
Permissible,
) {
readonly id: bigint
)
class User extends UserProto {
constructor(id: bigint) {
super()
this.id = id
}
}
const user1 = new User(BigInt(1))
const user2 = new User(BigInt(2))
const user1 = new User(1n)
console.log(user1)
console.log(user1.equals(user2))
console.log(user1.equals(user1))

View File

@@ -1,81 +0,0 @@
import { AbstractClass, AbstractConstructor, Opaque, UnionToIntersection } from "type-fest"
/**
* Represents the static members of a class.
*
* @template C - The type of the class for which static members are extracted.
* @typeparam The static members of the class.
*/
export type StaticMembers<C> = Pick<C, keyof C>
export type Trait<
C extends AbstractClass<any>
> = Opaque<
TraitApplier<C>,
"thilatrait/Trait"
>
export type TraitApplier<
C extends AbstractClass<any>
> =
(Parent: AbstractConstructor<any>) => C
export type UnwrapTraitC<T> =
T extends Trait<infer C>
? C
: never
export function trait<
C extends AbstractClass<any>
>(
applier: TraitApplier<C>
) {
return applier as Trait<C>
}
export function extendsAndExpresses<
C extends AbstractClass<any>,
Traits extends readonly Trait<any>[],
>(
extend: C,
traits: Traits,
) {
return traits.reduce(
(previous, trait) => trait(previous),
extend,
) as (
AbstractClass<
InstanceType<C> &
UnionToIntersection<
InstanceType<
UnwrapTraitC<
Traits[number]
>
>
>,
ConstructorParameters<C>
> &
StaticMembers<C> &
StaticMembers<
UnionToIntersection<
UnwrapTraitC<
Traits[number]
>
>
>
)
}
export function expresses<
Traits extends readonly Trait<any>[],
>(
...traits: Traits
) {
return extendsAndExpresses(Object, traits)
}