Consider these classes and model in typescript.
class ApplicantModel {
name: string = '';
}
abstract class BaseApplicant {
abstract handleApplicantData<T>(applicantData: T, isPrimaryApplicant: boolean): void;
}
class Applicant extends BaseApplicant {
handleApplicantData<ApplicantModel>(applicantData: ApplicantModel): void {
// Error: This type parameter might need an `extends ApplicantModel` constraint.
this.processApplicant(applicantData);
}
processApplicant(applicant: ApplicantModel): void {
console.log(applicant.name);
}
}
I’m getting error:
Argument of type 'ApplicantModel' is not assignable to parameter of type 'ApplicantModel'.(2345)
input.tsx(10, 23): This type parameter might need an `extends globalThis.ApplicantModel` constraint.
Why I need to use extends constraint. Why Argument of type ‘ApplicantModel’ is not assignable to parameter of type ‘ApplicantModel’?
2
Answers
In your case here:
ApplicantModel
refers to the name of the generic not the type, as@Palladium02 mentions.
What you want to do is this:
But since that throws an error as well you would have to do this in the BaseApplicant class:
Or if you want to keep it flexible:
This would still allow you to declare the function as generic in the subclass.
Final code would be:
I’d say your generics are inappropriately scoped. If
BaseApplicant
is a specific class with a generichandleApplicantData
method, then you’re saying that callers ofhandleApplicantData
can specify any type argument forT
that they want. Meaning someone could callnew Applicant().handleApplicantData(null)
if they wanted. But you don’t want or expectBaseApplicant
or any of its subclasses to be that flexible.If you want implementers to specify the type argument, then you really want
BaseApplicant
to be a generic class with a specifichandleApplicantData
method. That is, move the generic fromhandleApplicantData
toBaseapplicant
:Now instead of having your subclass try to make
handleApplicantData
generic somehow (which led to you trying and failing to specify the type argument asApplicantModel
, even though that was just the name of a new generic type parameter), your subclasses can choose whatT
is:This compiles as desired. An
Applicant
can only handleApplicantModel
. Some other subclass ofBaseApplicant
could handle some other data.Playground link to code