Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A mixin class must have a constructor with a single rest parameter of type any[] => this is wrong #59813

Closed
denis-migdal opened this issue Aug 31, 2024 · 3 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@denis-migdal
Copy link

denis-migdal commented Aug 31, 2024

πŸ”Ž Search Terms

None

πŸ•— Version & Regression Information

Tested on the nightly build.

⏯ Playground Link

Playground Link

πŸ’» Code

type Cstr<T> = {new(...args: any[]): T};

function mixins<T extends Cstr<any>>(klass: T) {

    return class Foo extends klass {

        readonly foo: number;

        constructor(foo: number, ...args: any[]) {
            super(...args);
            this.foo = foo;
        }
    }
}

πŸ™ Actual behavior

This raises the following error :

A mixin class must have a constructor with a single rest parameter of type any[]

πŸ™‚ Expected behavior

No TS errors should be raised.

Additional information about the issue

Instead of asking for a single rest parameters, TS should ask the last parameters to be a rest parameters.

Also, when #59812, is fixed, it should also be possible to do more complex constructor signatures, without relying on any[] :

type Cstr<T> = {new(...args: any[]): T};

type InferCstrParams<T> = T extends {new(...args: infer U): T} ? U : never;

function mixins<T extends Cstr<any>>(klass: T) {

    return class Foo extends klass {

        readonly foo: number;

        constructor(foo: number, ...args: InferCstrParams<T>) {
            super(...args);
            this.foo = foo;
        }
    }
}

Indeed, the constraints should be on the super() call, NOT on the mixins constructor.

This would also enable to generate the constructor parameters when the mixins e.g. has a type restrictions on klass, e.g. :

type Cstr<T, U extends any[]> = {new(...args: U): T};
function mixins<T extends Cstr2<any,[number]>>(klass: T) {

    return class Foo extends klass {
        constructor(a: number, b: number) {
            super(a+b);
        }
    }


}

This would also enable to create mixins taking many classes as parameters, etc.

@jcalz
Copy link
Contributor

jcalz commented Aug 31, 2024

You didn’t provide any search terms. Did you search for existing issues before filing this?
If you search for mixin constructor in:title there are lots of hits.

Duplicate #37143

@denis-migdal
Copy link
Author

denis-migdal commented Aug 31, 2024

From #14126

It seems a simple cast removes the error :

return class Foo extends (klass as { new(...args:[]): any }) {
    constructor(foo: number, b: boolean) { /* ... */ }
}

Note: if we want to add the base class parameters to the mixins class, we need to do another cast, cf the issue.

Playground Link

Seriously, why, for such simple code, are we forced to do such black magic found only in the darkness of the git issues ?

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Sep 6, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Sep 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants