Reputation: 39980
I'm trying to make a well-typed wrapper function that ultimately calls new FormGroup(), and I want to pass through parameters to it without just copy-pasting the signature.
TypeScript however complains that the FormGroup class type cannot be used as the type argument to TS's ConstructorParameters:
Type
FormGroup
does not satisfy the constraintnew (...args: any[]) => any
.
TypeFormGroup
provides no match for the signaturenew (...args: any[]): any
.
This can be reproduced by excerpting from the Angular .d.ts
:
declare interface AbstractControl { }
declare interface ValidatorFn { }
declare interface AbstractControlOptions { }
declare interface AsyncValidatorFn { }
declare class FormGroup {
constructor(
controls: {[key: string]: AbstractControl},
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
);
}
type FormGroupParams = ConstructorParameters<FormGroup>; // <= Error occurs here
What gives? Why is something declared as a class
with a constructor
not newable to TS? And is there a way I can access this signature?
Upvotes: 0
Views: 410
Reputation: 1135
The type signature that is implied by ConstructorParameters<T>
(i.e. the presence of new (...args: any[]) => any
) is checked only against the instance part of the class. However, the constructor is part of the static part of the class. The type checker does not see the presence of the constructor and hence gives you a type error. See the docs on this.
What you would need, however, would be a way of extracting from the static side to the instance part, as the following works as intended:
declare interface FormGroupConstructor {
new (
controls: {[key: string]: AbstractControl},
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
): FormGroup;
}
type FormGroupParams = ConstructorParameters<FormGroupConstructor>
The interface I've declared here is the type of the constructor function. In other words, you want to access the ConstructorParameters
of the type of the constructor. So, instead of
type FormGroupParams = ConstructorParameters<FormGroup>
you'd just do
type FormGroupParams = ConstructorParameters<typeof FormGroup>
Upvotes: 2