9

I have map function:

const map = <T, U>(f: (x: T) => U, arr: T[]): U[] => {
  return arr.map((val) => f(val));
}

When I'm calling map with anonymous function as a callback, it's return type is correct:

// `x1` variable type here is { name: string }[], which is correct
const x1 = map(x => x, [{name: 'John'}]);

But when I'm providing identity function instead of anonymous one, return type is wrong:

const identity = <T>(x: T) => x
// return type of `x2` is {}[] here
const x2 = map(identity, [{name: 'John'}]);

How to get correct type result for 2nd example, without providing explicit type arguments for map function?

4
  • 1
    What if you specify the return type as T on identity? Commented Jul 30, 2017 at 17:05
  • @jonrsharpe the same result.. Commented Jul 30, 2017 at 17:11
  • 2
    It works fine if you switch the order of map()'s arguments. I guess it forces the compiler to match the array element type first? I don't know if there's a way to get the inference to work in the order you have. Commented Jul 30, 2017 at 20:52
  • @jcalz nice find! I'll think on it, big thanks :) Commented Jul 30, 2017 at 21:00

1 Answer 1

3

After some trying, I honestly doubt TypeScript is able to follow you that far. For example:

const x4 = map(identity, [2]);
// x4 is '{}[]'

which is obviosly even more wrong than your example.

Some other tests:

const x2 = map(<({ name: string }) => { name: string }>identity, [{ name: 'John' }]);
// x2 is '{ name: string }[]'

And:

const double = (x: number) => 2 * x;
const x3 = map(double, [2]);
// x3 is 'number[]'

This lets me conclude that TypeScript just can't break all that generics down to a meaningful type and just says {}.

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

Comments

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.