-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
ConstructorParameters<T> cannot get parameters from an abstract superclass #31278
Comments
It's intentional that abstract classes don't present as having construct signatures (for obvious reasons); the limitation here is preferable to having some new relation for |
@RyanCavanaugh That may be preferable if it's an either-or situation, but if it's possible to fundamentally change the way abstract classes expose their constructors, that could be invaluable for situations that @aterisetri is describing in his example code (which is the same reason I'm here). i.e. Where you just want to pass constructor parameters through the prototype chain without redefining their properties every time. Here's another example. If the below code ran properly, we could add a new argument to the abstract class Animal {
constructor(public animalName: string) { }
}
abstract class Mammal extends Animal {
constructor(public numberOfNipples: number, ...animalArgs: ConstructorParameters<typeof Animal>) {
super(...animalArgs);
}
}
abstract class Montotreme extends Mammal {
constructor(public eggLayingCapacity: number, ...mammalArgs: ConstructorParameters<typeof Mammal>) {
super(...mammalArgs);
}
}
class Platypus extends Mammal {
constructor(public venomSeverity: number, ...monotremeArgs: ConstructorParameters<typeof Monotreme>) {
super(...monotremeArgs);
}
} |
For everyone who comes here looking for a solution, I found this workaround on reddit abstract class Test {
constructor(a: string, b: number) {}
}
type AbstractConstructorHelper<T> = (new (...args: any) => { [x: string]: any; }) & T;
type AbstractContructorParameters<T> = ConstructorParameters<AbstractConstructorHelper<T>>;
// Params resolved to [string, number]
type Params = AbstractContructorParameters<typeof Test>; |
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);
}
} The reason being is that the |
|
Using
ConstructorParameters<typeof Superclass>
allows your constructor to share the same arguments as your superclass without copy and pasting them, but it doesn't work for concrete implementations of abstract classes because the superclass isn't newable.#23911 would provide an alternative way to avoid the copy and paste.
TypeScript Version: 3.5.0-dev.20190504
Search Terms: ConstructorParameters, abstract, newable
Code
Expected behavior: Bar compiles with no error.
Actual behavior:
Playground Link: https://www.typescriptlang.org/play/#src=abstract%20class%20Foo%20%7B%0D%0A%09constructor(public%20a%3A%20number%2C%20public%20b%3A%20string)%20%7B%0D%0A%09%7D%0D%0A%0D%0A%09abstract%20doSomething()%3A%20void%3B%0D%0A%7D%0D%0A%0D%0Aclass%20Bar%20extends%20Foo%20%7B%0D%0A%09constructor(...args%3A%20ConstructorParameters%3Ctypeof%20Foo%3E)%20%7B%0D%0A%09%09super(...args)%3B%0D%0A%0D%0A%09%09%2F%2F%20some%20other%20code%20here%0D%0A%09%7D%0D%0A%0D%0A%09doSomething()%20%7B%0D%0A%09%7D%0D%0A%7D
Related Issues: #30991, #23911
The text was updated successfully, but these errors were encountered: