1
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?

1

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you explain what you mean by type parameter forwarding?
@Wex The <T> on the parameter function is forwarded to the return of the generate function. The type parameter on g was not explicitly defined anywhere but instead comes from the fact that init was generic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.