Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thoughts about variadic generics? #1773

Closed
sccolbert opened this issue Jan 22, 2015 · 12 comments
Closed

Thoughts about variadic generics? #1773

sccolbert opened this issue Jan 22, 2015 · 12 comments
Labels
Suggestion An idea for TypeScript

Comments

@sccolbert
Copy link

We can kind of already do this for functions by defining several overloads, but there is no corresponding mechanism for overloaded classes or interfaces. A typical use case would be defining a registry for callbacks which accept a number of parameters. Something like the following with loosely proposed variadic type syntax:

interface IDispatcher<...ArgTypes> {

  add(callback: (...args: ArgTypes) => void): void {
    // store the callback
  }

  dispatch(...args: ArgTypes): void {
    // invoke the callbacks
  }
}


function createDispatcher<...ArgTypes>(): IDispatcher<...ArgTypes> {
  // create a concrete instance
}


var d = createDispatcher<number, string>();
@DanielRosenwasser
Copy link
Member

Seems somewhat related to #1024.

@danquirk danquirk added the Suggestion An idea for TypeScript label Jan 22, 2015
@danquirk
Copy link
Member

I believe we also talked about this as one potential way to describe a mixin function.

@sccolbert
Copy link
Author

The use case I'm attempting to describe here is indeed the same as the dispatcher case mentioned in #1024

@NN---
Copy link

NN--- commented Mar 16, 2015

Variadic generic can make functions like 'setTimeout' more type-safe.
Instead of:

declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

Now you must do something like:

declare function setTimeout(handler: () => void, timeout?: any): number;
declare function setTimeout<P0>(handler: (p0: P0) => void, timeout: any, p0: P0): number;
declare function setTimeout<P0, P1>(handler: (p0: P0, p1: P1) => void, timeout: any, p0: P0, p1: P1): number;
...  P2 ... Pn
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

And with variadics it will be simple:

function setTimeout(handler: () => void, timeout?: any): number;
function setTimeout<T...>(handler: (t: T...) => void, timeout: any, t: T...): number;
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

@RyanCavanaugh RyanCavanaugh added In Discussion Not yet reached consensus Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. and removed In Discussion Not yet reached consensus labels Mar 17, 2015
@dead-claudia
Copy link

Ping, anyone? Just making sure this doesn't get lost in the shuffle.

As for actual functions (not simply declared), there should be a requirement that variadic parameters cannot be accessed directly as arrays - you should only be allowed to spread those parameters in calls to other functions. Otherwise, it's near impossible to correctly check the type of the parameter accessed, as TypeScript doesn't have dependent types and higher order types, both of which would be required to support parameter access. (Haskell uses that for hackish support for variadic types in the first place.)

I think C++ has a similar condition, although please correct me if I'm wrong (I'm not as familiar with C++).

@sandersn
Copy link
Member

sandersn commented Nov 5, 2015

@IMPinball, #5453 addresses your concern by disallowing parameter access. I'll take a look at C++'s variadic template arguments today to see how it's handled there.

@dead-claudia
Copy link

Interesting. It almost looks like Japanese to me, even though I can somehow
comprehend it.

On Thu, Nov 5, 2015, 09:41 Nathan Shively-Sanders [email protected]
wrote:

@IMPinball https://github.com/impinball, #5453
#5453 addresses your
concern by disallowing parameter access. I'll take a look at C++'s variadic
template arguments today to see how it's handled there.


Reply to this email directly or view it on GitHub
#1773 (comment)
.

@sandersn
Copy link
Member

sandersn commented Nov 6, 2015

C++ has an additional operator, sizeof..., that lets you get the length of a tuple kind (called parameter packs there). Otherwise it's quite similar to my proposal.

@Artazor
Copy link
Contributor

Artazor commented Dec 14, 2015

Would be great to see this feature!

@eric-wieser
Copy link

This no longer needs the "Needs proposal" tag in light of #5453, right?

@sandersn sandersn removed the Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. label Oct 3, 2016
@sandersn
Copy link
Member

sandersn commented Oct 3, 2016

Good catch. #5453 indeed covers this issue and discussion should continue there.

@sccolbert
Copy link
Author

Closing in favor of #5453

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

9 participants