microsoft/TypeScript

"design:paramnames" metadata key

remojansen opened this issue · 11 comments

From #2589

A few notes on metadata:

  • Type metadata uses the metadata key "design:type".
  • Parameter type metadata uses the metadata key "design:paramtypes".
  • Return type metadata uses the metadata key "design:returntype".

Can you please add support for a "design:paramnames" metadata key? It would return the design-time names of the arguments of a function

I can convert a function to string at runtime using Function.prototype.toString() and then use a couple of Regex to get the parameter names:

STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
ARGUMENT_NAMES = /([^\s,]+)/g;

But when a minifier/compressor is used the param names become "a", "b" ...

I would like to have a way to access the design-time names of the arguments of a function at run-time even after compression.

If I may ask, what's the use case of this?

@RichiCoder1 Sure, I'm working on a inversion of control container and I want to add contextual binding support. One of the things that I want to allow developers to do is to use constraints based on the injection target. Take for example:

class Soldier {

  private _mainWeapon : IWeapon;
  private _secondaryWeapon : IWeapon;

  constructor(main : IWeapon, secondary : IWeapon) { // injections
    this._mainWeapon = main;
    this._secondaryWeapon = secondary;
  }
}

When I declare the bindings I can use a constraint to resolve ambiguous bindings:

kernel.bind(new Binding<IWeapon>(Katana).when((target) => { return target.name === "main" }));
kernel.bind(new Binding<IWeapon>(Shuriken).when((target) => { return target.name === "secondary" }));

My problem is that If the javascript is compressed, the value of target.name would be "a" and "b" and the IoC container would not be able to resolve the service.

Ahh, that would make sense.

I would love to see this added.

Hi @mhegazy It's been a while since this was tagged as In Discussion. Do you have an update on this? Thanks!

We do not intend to make any changes to decoratos implementation until the TC39 discussions about the current proposal are finalized. there will be some changes that we need to make with the latest draft of the proposal; after that is done, we can look into adding these additional feature requests.

isuda commented

@mhegazy - Its been a year since your last comment on this. Any updates on when this might be able to be implemented? It would be super useful to be able to use this to do DI when code has been minified.

I'd also love to see this implemented as it would allow me to map the properties of an object (input parameters from a GraphQL query) on to the parameters of a function (the resolver). I was hoping to find a way to augment the metadata emitted by tsc but it seems compiler plug-ins are not yet a thing.

While we're at it, knowing the type a promise will return would also be very useful so metadata for generics too, please.

+1. At LoopBack, we introduce decorators to annotate method parameters to describe how to map methods to REST APIs. It will be great that we can infer parameter types/names from the design time metadata. For example:

@returnValue()
async createOrder(@param() order: Order): Promise<Order> {
  // ...
}

We would like to know:
- The parameter name ('order') N/A today
- The parameter type (Order) (It's already supported, but not for array item types)
- The return type (Promise) but we care more about `Promise<Order>`
nodkz commented

Duplicate #12626