Home > front end >  TypeScript doesn't check return type when use generic
TypeScript doesn't check return type when use generic

Time:07-02

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.

playground

CodePudding user response:

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

  • Related