question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Parameters does not factor in generics or overloads

See original GitHub issue

Bug Report

🔎 Search Terms

  • “parameters with generic function”
  • “generic function wrapping”

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Type System Behavior, Generics,

⏯ Playground Link

Playground link with relevant code

💻 Code

declare function foo<TState, T>(
  s1: TState,
  project: (s1: TState) => T): T;
declare function foo<TState1, TState2, T>(
  s1: TState1,
  s2: TState2,
  project: (s1: TState1, s2: TState2) => T): T;

// This is not what I would expect
type Args = Parameters<typeof foo>; // = [s1: unknown, s2: unknown, project: (s1: unknown, s2: unknown) => unknown]

// Something I would have expected
type Expected<TState, T, TState1, TState2> =
  [s1: TState, project: (s1: TState) => T]
  | [s1: TState1, s2: TState2, project: (s1: TState1, s2: TState2) => T];


// Even if it were to return the expected type, it still would not work
function wrapper<TState, T, TState1, TState2>(...args: Expected<TState, T, TState1, TState2>) {
  return foo(...args);
  //         ^^^^^^^ Expected 2-3 arguments, but got 0 or more.(2556)
}

🙁 Actual behavior

The Parameters type seems to choose either the last or a random overload of the given method instead of all of them. Also doesn’t factor in generics and converts them to unknown instead. Even if it would return what I would have expected (see Expected type in example), it still isn’t usable in practice.

🙂 Expected behavior

That Args would result in something similar to Expected. All of the overloads should be factored in and also generics. The Expected args should be usable on foo.

Real-world usages

Any wrapper function where the original function is complex, has overloads or is generic. In our case, it’s everything 😃

More specifically I want to reduce boilerplating with @ngrx so I wanted to wrap the function createSelector which is declared here, which is similar to the foo of my example, but with 31 overloads instead of only 2 and where the return type is dependent on the parameters (the project argument).

Wrapping this method is possible, but requires just an insane amount of copy-pasting with some little changes which isn’t feasible and does not exactly help in reducing the amount of code.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:7
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
MartinJohnscommented, Apr 19, 2021

Parameters<T> is based on type inferrence in conditional types, and type inferrence in conditional types does not support overloading: https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types

This is a known design limitation.

0reactions
MartinJohnscommented, Apr 21, 2021

Because WrapperType is not generic. You can’t pass along generic types like this. I think this would require #1213.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript: function overload doesn't work with generics
I am trying to get function overloads working with a function that takes a generic type param. Originally I have a function foo...
Read more >
Overloading and generic constraints - Jon Skeet's coding blog
The first bullet is fine: we have a single type argument, and both methods have a single type parameter. So what about the...
Read more >
Restrictions on Generics (The Java™ Tutorials > Learning the ...
A class's static field is a class-level variable shared by all non-static objects of the class. Hence, static fields of type parameters are...
Read more >
Re: No generics, no overloading, and no adding methods to ...
Generics. Yeah, I know Google doesn't like them. But how else are you gonna define a function that takes a parameter of type...
Read more >
Different ways of Method Overloading in Java - GeeksforGeeks
It would be a compiler error. The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found