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

Add new type: AbstractConstructorParameters<T> #160

Open
hackape opened this issue Jan 6, 2021 · 1 comment
Open

Add new type: AbstractConstructorParameters<T> #160

hackape opened this issue Jan 6, 2021 · 1 comment

Comments

@hackape
Copy link

hackape commented Jan 6, 2021

Is your feature request related to a real problem or use-case?

Utility type to get constructor params from abstract class. TS built-in ConstructorParameters does not work on abstract class type since it's not constructible.

abstract class AbstractBase {
  constructor(foo: string, bar: number) {}
}

class Child extends AbstractBase {
  constructor(...args: ConstructorParameters<typeof AbstractBase>) {
    super(...args)
  }
}

/**
 * Error:
 * Type 'typeof AbstractBase' does not satisfy the constraint 'new (...args: any) => any'.
 * Cannot assign an abstract constructor type to a non-abstract constructor type.ts(2344)
 */

Describe a solution including usage in code example

Solution:

type AbstractConstructorParameters<T> = ConstructorParameters<(new (...args: any) => any) & T>

Usage:

abstract class AbstractBase {
  constructor(foo: string, bar: number) {}
}

class Child extends AbstractBase {
  // now it works!
  constructor(...args: AbstractConstructorParameters<typeof AbstractBase>) {
    super(...args)
  }
}

Who does this impact? Who is this for?

Typescript user, generally useful in OOP.

Credit

Found this workaround here, which in turn refers to this reddit post by u/adamuso

@CMCDragonkai
Copy link

This doesn't work for object destructured assignment:

type AbstractConstructorParameters<T> = ConstructorParameters<(new (...args: any) => any) & T>;

abstract class Test {
    constructor ({
        a,
        b
    }: {
        a: string,
        b: string
    }) {
        console.log(a);
    }
}

class Test2 extends Test {
    constructor (
        {
            c: string,
            ...rest
        }: {
            c: string;
            rest: AbstractConstructorParameters<typeof Test>
        }
    ) {
        super(...rest);
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants