awmleer
awmleer

Reputation: 1800

typescript generic type inference in higher order function

function generate<P extends object>(init: (p: P) => void) {
  return function (p: P): P {
    init(p)
    return p
  }
}

const g = generate(function AAA<T>(p: T) {
  console.log(p)
})

const result = g({
  x: 1
})

result.x // TS2339: Property 'x' does not exist on type '{}'.

The generate function is a higher order function and it seems typescript can't deduce the generic type P.

How can I make generate able to accept a generic typed function as parameter?

Upvotes: 1

Views: 598

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250136

Typescript 3.4 makes huge improvements around the handling of generic type parameter forwarding. You can read the details here.

While your code will not work as is in 3.4 either, we can get it to work if we change the init function to take in a generic tuple argument. This will cause type parameter forwarding to kick in:

function generate<A extends [any]>(init: (...p: A) => void) {
    return function (...p: A): A[0] {
        init(...p)
        return p
    }
}

const g = generate(function AAA<T>(p: T) {
    console.log(p)
})

const result = g({
    x: 1
})

result.x // ok now

You can test this code yourself if you run npm install typescript@next.

Upvotes: 1

Related Questions