Issue
say we have the following code :
class Foo<T> {
lift<R>(): Foo<R> {
const bar = new Foo<T>()
return bar
}
}
why there is no error? Foo<T>
and Foo<R>
may be different type.
Solution
TS uses structural type matching and not nominal. This means that 2 types are compatible if their structure is compatible.
You can read about how matching happens for generics here.
The reason your example works is that from a structure point of view there isn't anything that differentiates between Foo<string>
or Foo<number>
for instance. This is gonna work in TS
const a: Foo<string> = new Foo<number>()
This is also the reason why your function works, because Foo<TypeA>
is compatible with Foo<TypeB>
for any TypeA
and TypeB
.
If you add anything else that use T
then the structural compatibility is broken and you get the error you are expecting:
class Foo<T> {
field: T | null = null
lift<R>(): Foo<R> {
const bar = new Foo<T>()
return bar
}
}
Type 'Foo<T>' is not assignable to type 'Foo<R>'.
Type 'T' is not assignable to type 'R'.
'R' could be instantiated with an arbitrary type which could be unrelated to 'T'.(2322)
You can see this in action here
Answered By - Radu Diță
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.