Repository navigation
Get type of parameter list of a function (parametersof?) #26019
Copy link
Copy link
Closed
Labels
QuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
Description
Search Terms
type of function's parameters list; type of arguments list; tuples;
Suggestion
There are functions a() and b(). Function a() have the same signature (parameters) as function b().
Instead of manually copying list of parameters with their types from b() to a(), there should be a way to assign types of parameters to a() from b().
function a(...args: /* possible syntax starts */ parametersof b /*possible syntax ends*/ ) {
b(...args)
}
function b (a: string, b: number) { /* ... */}
a('foo', 1) // ok
a('foo', 'bar') // compiler error "Argument of type 'bar' is not assignable to parameter of type 'number'"parametersof ... should probably return a tuple.
Related question on Stackoverflow
Use Cases
- Decorators or simply reusing existing functions:
function a(...args: parametersof b) {
// ... do some stuff
b(...args)
}- API that provides lazy-loaded functions or provides functions based on environment:
import someFunc from './someFunc'
export const someAPI = {
someFunc, // normal one, we just re-exporting this func
async lazyFunc(...args: parametersof eagerFunc) {
const {eagerFunc} = await import('./eagerFunc')
return eagerFunc(...args)
}, // lazy func. helps to reduce main bundle
get node() {
if (runningInNode()) {
return {
async nodeFunc(...args: parametersof nodeFunc) {
const {nodeFunc} = await import('./nodeFunc')
return nodeFunc(...args)
}
}
}
} // here we do not add code, that is supposed to work only in node.js, to frontend bundle)
}Current workarounds and their faults
function a(a: string, b: number) {
b(...args)
}
function b (a: string, b: number) {/*...*/}Above practice have these disadvantages:
- When changing
b's signature, we also have to changea's one. That is little bit harder maintenance and a window for new errors. - Contradicts with DRY principle
Comparison to tuples
I am aware of new "tuples" feature in TS 3.0, which is great! However using tuples for this use case requires creating new types, while "parametersof" solution will end up in minimum possible amount of code and maximum readability.
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)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
QuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
Activity
bterlson commentedon Jul 27, 2018
Somewhere, Anders Hejlsberg (@ahejlsberg) proposed adding the following definition to lib.d.ts:
I think this is the right way to go here over a new operator.
If it's useful, here's ReturnType as well:
anurbol commentedon Jul 27, 2018
Brian Terlson (@bterlson) thank you for quick response!
My thoughts on the solutions provided by you:
T(I guess a function?).P.S. And yes! I forgot about return types, they are also should have some way to be assigned from one func to another.
bterlson commentedon Jul 27, 2018
Nurbol Alpysbayev (@anurbol) if it gets added to lib.d.ts you can just use
Parameters<some function type>without understanding how it works (much like howPickorRecordwork today).Probably the best resource to understand this stuff is the 2.8 release blog.
ParametersandReturnTypeare conditional types using theinferkeyword in the conditional to tell TS to inferT's argument list or return type respectively.bterlson commentedon Jul 27, 2018
Also, here's an example of using
Parameters:anurbol commentedon Jul 28, 2018
Thank you, Brian Terlson (@bterlson)! I love TS even more now! ❤️ And ReturnType (BTW one does not have to add it to lib.d.tsm it is already included in the core lib), fantastic!
rsolomon commentedon Aug 3, 2018
Brian Terlson (@bterlson) using TS 3.0.1, it seems like the definition above for
Parametersjust returns an empty Object type. Ex:Yields
Any ideas on what might be wrong? Or is re-using function argument types for new functions not yet supported?
EDIT: Nevermind, this does work in 3.0. I had a dependency in my test repo that was pulling in the wrong version.
pleerock commentedon Dec 21, 2019
is there any possibility to extract parameter names as well? e.g.
edit: probably I want too much and parameter names don't relate to type system..
dragomirtitian commentedon Dec 22, 2019
Umed Khudoiberdiev (@pleerock) There is no way to extract the parameter names to an object type.
Parameter names will however be preserved if you extract form one function and spread to another function:
Playground Link
pleerock commentedon Dec 22, 2019
Thanks Titian Cernicova-Dragomir (@dragomirtitian). That's interesting behavior. However I wanted to create an object type out of parameter names, e.g. { x: number, y: number }
dianjuar commentedon Mar 16, 2020
What if you only have one parameter and want that parameter, not an array with that parameter?
dragomirtitian commentedon Mar 16, 2020
Diego Julião (@dianjuar)
Playground Link
bhishp commentedon Jun 2, 2020
In a similar vein to this, is it possible to first define the args expected and then use them in both functions? For example...
It doesn't really make sense in the above snippet alone but what I am interested in is reducing boilerplate when it comes to function overloading. If we want the return type to be narrowed based on an input
This works but is only a trivial number of args, so could be more boilerplate to copy and paste. Is it possible for something like...
I have attempted using conditional types but have not managed to do so far...
EDIT
Additionally it would be nice to add some type-safety to the function implementation, along the lines of:
aztack commentedon Nov 5, 2020
Bhish (@bhishp)
I think the parameters only exist in
value space: They are not keys(string | number) of an object but variables.Even you get a type like
[arg0: string, arg1, number]by writingParameters<some-function-type>,the parameter names are lost in the
type space.Thyregod commentedon Feb 24, 2021
Bhish (@bhishp) I am curious. Did you find a solution to your latest question concerning spreading the properties of a type as arguments to a function?
bhishp commentedon Feb 24, 2021
I'm afraid not, sorry