You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As of #24897, we can now use rest types in tuples to type argument lists. This is very nice since it allows us to easily type a couple of common methods. However there's still one big offender, which are the NodeJS callback style API methods. These generally accept a couple of arguments, with the callback method being the last one. Borrowing from the example in the RC-3.0 docs:
functionnodeJsCallbackAPI<TReturn>(callback: (err: Error|undefined,result: TReturn)=>void);functionnodeJsCallbackAPI<T1,TReturn>(arg1: T1,callback: (err: Error|undefined,result: TReturn)=>void);functionnodeJsCallbackAPI<T1,T2,TReturn>(arg1: T1,arg2: T2,callback: (err: Error|undefined,result: TReturn)=>void);functionnodeJsCallbackAPI<T1,T2,T3,TReturn>(arg1: T1,arg2: T2,arg3: T3,callback: (err: Error|undefined,result: TReturn)=>void);// AHH, how many overloads is enough?functionnodeJsCallbackAPI(...args: any[]){// do work, call callback!}
While rest parameters need to be the last in JavaScript, this limitation doesn't have to apply to the type system in TypeScript. I would love to see the ability for rest types to appear anywhere in a tuple type, e.g. like this:
typeT1=[...string[],number];// any amount of strings, followed by a number. (length >= 1)typeT2=[number, ...string[],number];// a number, followed by any amount of strings, followed by a number. (length >= 2)typeT3=[...string[],number?];// any amount of strings, optionally followed by a number. (length >= 0)typeT4=[number, ...string[],number?];// a number, followed by any amount of strings, optionally followed by a number. (length >= 1)// bonus points, not sure if that is logical or even well-defined, when there are overlapping types:typeT5=[number?, ...string[],number?];// an optional number, followed by any amount of strings, optionally followed by a number. (length >= 0)typeT6=[...string[],number, ...string[]];// any amount of strings, followed by a number, followed by any amount of strings. (length >= 1)// weird thoughts, do these make sense?typeT7=[...any[],number,(number|string)?];// Could be anything, followed by [number] or [number, number] or [number, string]...typeT8=[...any[],number, ...any[]];// anything, but there must be a number
With this functionality in place, we could type the above methods like this:
// This is just a Type-Script internal overload, rest arguments should be allowed to appear whereever they may appear in tuple typesfunctionnodeJsCallbackAPI<TArgsextendsany[],TReturn>(...args: TArgs,callback: (err: Error|undefined,result: TReturn)=>void);// This is the "official"/external overload. Therefore we cannot use rest arguments as the first argument and need to split the callback arg manuallyfunctionnodeJsCallbackAPI(...args: any[]){// split args from callback, do more work}
Checklist
My suggestion meets these guidelines:
This wouldn't be a breaking change in existing TypeScript / JavaScript code
This wouldn't change the runtime behavior of existing JavaScript code
This could be implemented without emitting different JS based on the types of the expressions
This isn't a runtime feature (e.g. new expression-level syntax)
The text was updated successfully, but these errors were encountered:
@mhegazy I'm not sure how it looks like "under the hood", but it seems like #1360 is only concerned with the function signatures.
This issue also includes tuple types, which have just gotten the ability to include rest types. Do you count that part of my proposal as part of #1360 too?
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Search Terms
rest element type tuple last
Related:
#24897
Suggestion
As of #24897, we can now use rest types in tuples to type argument lists. This is very nice since it allows us to easily type a couple of common methods. However there's still one big offender, which are the NodeJS callback style API methods. These generally accept a couple of arguments, with the callback method being the last one. Borrowing from the example in the RC-3.0 docs:
While rest parameters need to be the last in JavaScript, this limitation doesn't have to apply to the type system in TypeScript. I would love to see the ability for rest types to appear anywhere in a tuple type, e.g. like this:
Use Cases
Typing the
promisify
andcallbackify
methods and similar patterns. Currently they look like this monster, which is inherently incomplete:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/91f8a6b7d1ef61cc543d0901dcc004b846283345/types/node/index.d.ts#L6275
Examples
With this functionality in place, we could type the above methods like this:
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: