Generic interfaces and classes, I like them and I think they are very useful . I have just started using them and I would like to understand why I am having the 2 errors I have in the TS playground (link). I would appreciate any help, THANKS in advance.
Issue 1: returned variable o (Person.fromJson(j)
) implements IPerson<T,K>
and T is a extension of IPerson<T,K>
so I don't understand why is wrong. I did a basic use case with no generic classes at the end of the TS playground and I don't see the same error.
Description error: in the return o of Person.fromJson(j)
Type 'Person<IPerson<unknown, JsonPerson>, JsonPerson>' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Person<IPerson<unknown, JsonPerson>, JsonPerson>'
class Person<T extends IPerson<T,K>, K extends JsonPerson> implements IPerson<T,K>{
name: string = "Unknown"
constructor(){}
toJson(): JsonPerson{
return {"name": this.name}
}
fromJson(j: K): T{
let o= new Person()
o.name = j.name
return o
}
}
Issue 2: The error states "Type T does not satisfy....", but if T extends IStudent
and IStudent
extends IPerson
. So T "extends IPerson"? I think that yes (inclusion principle). So that is why I don't understand the next error. Maybe it refers that it does not satisfy due to fromJson incompatibility but not sure how to solve it. Maybe this comes from Issue 1.
Description error: in extends Person<T,K>
Type 'T' does not satisfy the constraint 'IPerson<T, K>'. Type 'IStudent' is not assignable to type 'IPerson<T, K>'. The types returned by 'fromJson(...)' are incompatible between these types. Type 'IStudent' is not assignable to type 'T'. 'IStudent' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'IStudent'.
class Student<T extends IStudent, K extends JsonStudent> extends Person<T,K>
implements IStudent{
student: boolean= true
constructor(){
super()
}
toJson():JsonStudent{
return {...super.toJson(), "student":this.student}
}
fromJson(j: K): T{
let o: T = super.fromJson(j)
o.student=j.student
return o
}
}