Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function that return a generic type not work without a concrete type

Tags:

typescript

I expect this code works but is not:

interface Foo {
  foo(): boolean;
}

interface GenericFoo<T = {}> {
  bar(): T
}

function testFoo<T extends Foo>()
 : GenericFoo<T> {
// : GenericFoo<Foo> {
  return {
    bar() {
     return {
       foo() { return true },
     }
    },
  }
}

Setting return of testFoo to:

GenericFoo<Foo> // Typecheck OK

Not work

GenericFoo<T> // Typecheck FAIL

What will be the correct way to do this??

like image 981
Flx Files Avatar asked Mar 17 '26 22:03

Flx Files


1 Answers

Just because T extends Foo does not mean the object literal { foo() { return true } } will be compatible with T.

What if T is defined as { foo(): boolean, goo(): string } at call site. This call is valid, as the type extends Foo but the function does not supply the bar method as the caller would expect

The only way to get the compiler to stop complaining is to use a type assertion, although as highlighted above this is not type safe:

interface Foo {
    foo(): boolean;
}

interface GenericFoo<T = {}> {
    bar(): T
}

function testFoo<T extends Foo>()
    : GenericFoo<T> {
    return {
        bar() {
            return {
                foo() { return true },
            } as T
        },
    }
}

testFoo<Foo>().bar().foo() //ok
testFoo<{ foo(): boolean; goo(): string }>().bar().goo() // runtime error 
like image 145
Titian Cernicova-Dragomir Avatar answered Mar 20 '26 17:03

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!