Repository navigation
Generic type constraint does not apply to rest parameters #2328
Description
Activity
This is technically by design but it's a reasonable suggestion. We also don't allow subtypes of array without generics.
- addedIn DiscussionNot yet reached consensusNot yet reached consensus
on Mar 17, 2015 RyanCavanaugh commented
on Mar 17, 2015 MemberMore actionsSpec section 3.8.2.2
- addedBy DesignDeprecated - use "Working as Intended" or "Design Limitation" insteadDeprecated - use "Working as Intended" or "Design Limitation" insteadand removedIn DiscussionNot yet reached consensusNot yet reached consensusSuggestionAn idea for TypeScriptAn idea for TypeScript
on May 4, 2015 RyanCavanaugh commented
on May 4, 2015 MemberMore actionsThis doesn't actually make sense.
The function should be rewritten this way:
function attach<T>(cb: (...args: T[]) => void): void { }
Any production that requires that you write
Tinstead ofT[]would require a lie, because the type of the rest arg is always going to be the basicArraytype, not some subtype thereof. It would be especially dangerous to flow that type through.JoshuaKGoldberg commented
on Sep 8, 2016 ContributorMore actionsRyan Cavanaugh (@RyanCavanaugh) what if the function is meant to be used like the following?
attach((age: number, name: string) => { console.log({ age, name }); }); // written explicitly: attach<[number, string]>(/*... */);
Using the
...args: T[]approach we would then have this typed as(number | string)[]instead of[number, string]right?Reacted by Yoshi WalshRyanCavanaugh commented
on Sep 8, 2016 MemberMore actionsIf that's the desired behavior you'd be better off writing some explicit overloads e.g. https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/underscore/underscore.d.ts#L1126
Reacted by Josh Ghoulberg 👻Reacted by Yoshi WalshAs a library author this makes me sad, since with overloading you lose the parameter name information. Plus it produces ugly inline documentation.
Reacted by Ian Copp and Yoshi WalshI'd love to see this decision reconsidered. As I understand it, one of TypeScript's major design goals is to have a type system flexible enough to represent any common JavaScript design pattern. Rest parameters have been supported for years, and generics are a vital part of TypeScript, the fact that you can't use both together is unfortunate.
I'd also like to be able to use this feature. I'm building an abstract command pattern class that I'd like to do something like this for:
abstract class Command<T extends any[]> { public load(...args: T); public loadIfNeeded(...args: T); public clearAndReload(...args: T); }Requiring implementing classes to override every method in the abstract class just to provide a type definition is ugly. Implementing this issue's feature would solve this nicely.
- locked and limited conversation to collaborators
on Jul 25, 2018
The following fails to compile even though T is constrained to an array type: