question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Recursive definitions in mixins

See original GitHub issue

Its currently possible to create a circular references in classes just fine:

export class Class1 {
    another     : Class2     // compiles fine
}
export class Class2 {
    another     : Class1    // compiles fine
}

However, the same thing fails when using mixin-based classes:

export const SampleMixin1 = <T extends AnyConstructor<object>>(base : T) =>
class SampleMixin1 extends base {
    another             : SampleMixin2 // TS2502: 'another' is referenced directly or indirectly in its own type annotation
}
export type SampleMixin1 = Mixin<typeof SampleMixin1>


export const SampleMixin2 = <T extends AnyConstructor<object>>(base : T) =>
class SampleMixin2 extends base {
    another             : SampleMixin1 // TS2502: 'another' is referenced directly or indirectly in its own type annotation
}
export type SampleMixin2 = Mixin<typeof SampleMixin2>


// supporting declarations for mixin pattern
export type AnyFunction<A = any>      = (...input: any[]) => A
export type AnyConstructor<A = any>   = new (...input: any[]) => A
export type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>

This makes things much more complicated, you need to introduce some dummy interfaces, etc, etc.

The workaround exists - to use different form of creating the type for the standalone mixin class - with interfaces:

export const SampleMixin3 = <T extends AnyConstructor<object>>(base : T) =>
class SampleMixin3 extends base {
    another             : SampleMixin4
}
export interface SampleMixin3 extends Mixin<typeof SampleMixin3> {}


export const SampleMixin4 = <T extends AnyConstructor<object>>(base : T) =>
class SampleMixin4 extends base {
    another             : SampleMixin3
}
export interface SampleMixin4 extends Mixin<typeof SampleMixin4> {}

But this notation seems to drive crazy the IDE (the language server under the hood?). It stop finding usages of properties, show many false type errors etc. Basically in such approach you are limited to old-good console npx tsc launch (which works well at least), but all the development aid facilities don’t work.

I think mixin pattern should be supported first class. I’d even create some language construct for it.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:15
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
canonic-epicurecommented, May 9, 2019

Any hope for a proper solution of this issue?

0reactions
canonic-epicurecommented, Jul 21, 2021

@trusktr Can you try making it working as in my 2nd example here? Basically, create a SampleMixin3 which extends SampleMixin1 and SampleMixin4, which extends SampleMixin2. Then make a cycle between them

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sass recursion mixin - Stack Overflow
The recursive approach here is the same as another languages, you have to use the parameter to call the function again, and when...
Read more >
Mixin modules in a call-by-value setting - Archive ouverte HAL
Abstract. The ML module system provides powerful parameterization facilities, but lacks the ability to split mutually recursive definitions.
Read more >
A Reduction Semantics for Call-by-value Mixin Modules
dependencies between mixin components, in order to con- strain the evaluation order. Recursion Many programming languages restrict recursive definitions ...
Read more >
Extended recursive definitions in call-by-value languages with ...
Extended recursive definitions in call-by-value languages with applications to mixin modules and recursive modules. Tom Hirschowitz. Xavier Leroy.
Read more >
Rigid Mixin Modules | SpringerLink
Mixin modules are a notion of modules that allows cross-module recursion and late binding, two features missing in ML-style modules.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found