npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

parameters-decorator

v0.3.0

Published

A method decorator to bring parameter decorators to ECMAScript (based on the TC39 proposal)

Downloads

49

Readme

parameters-decorator

This library exports ECMAScript decorators that adds support for parameter decorators

Only standard decorators are supported, not TypeScript experimental decorators; it's tested with both Babel's @babel/plugin-proposal-decorators and TypeScript 5+.

API

Note that below, when it's said that a parameter decorator is conditionally applied, or that it will be applied to specific values, this is only about the function that such a parameter decorator can return. The parameter decorator itself will only be called once, and unconditionally, when the class is initialized; the returned function will be called (or maybe not) each time the annotated method is invoked.

@parameters()

The parameters decorator can annotate classes or class methods and allows applying parameter decorators to their parameters (or the parameters of the class constructor). Note that because the parameter name, or whether the parameter is a rest parameter of a variadic function, cannot be determined at runtime, those informations must be specified explicitly.

The parameters decorator takes as many arguments as the function it annotates, where each argument represents the decorator(s) to apply to the corresponding function parameter. Those can thus take different forms:

  • undefined to skip the parameter and not apply any decorator to it
  • a single parameter decorator
  • an array of parameter decorators, optionally prefixed with the parameter name and/or whether it's a rest parameter (both optional but in this order)
  • an object with a decorators property as an array of parameter decorators, and optional properties name and rest

The following example, using the syntax from the ECMAScript proposal:

class Cls {
  constructor(@A param1, param2, @B @C param3) { }

  method(@D @E param1, @F @G param2, @H ...rest) { }
}

can be written using the parameters decorator as (examplifying the various forms):

@parameters(A, undefined, { name: "param3", decorators: [B, C] })
class Cls {
  constructor(param1, param2, param3) {}

  @parameters(["param1", D, E], [F, G], ["rest", true, H])
  method(param1, param2, ...rest) {}
}

@parameter()

The parameter decorator is the equivalent of parameters but for a setter. Because there can only be a single parameter, it takes an optional parameter name as the first argument, followed by a list of parameter decorators. It can also take a single object as argument with a decorators property as an array of parameter decorators, and an optional name property.

class Cls {
  @parameter("value", A, B)
  set prop1(value) {}

  @parameter(A)
  set prop2(value) {}
}

@rest()

The rest parameter decorator allows applying a set of parameter decorators to each value of a rest parameter (each argument of the actual invocation) rather than the array of values.

class Cls {
  @parameters([true, rest(A, B)])
  method(...rest) {}
}

// The A and B decorators will each be called 3 times,
// for each one of the "one", "two", and "three" values.
new Cls().method("one", "two", "three");

@defaultValue()

The defaultValue parameter decorator allows assigning a default value to an optional parameter before other decorators (parameter or class/method/setter) are applied. Because decorators are applied first-to-last, this decorator should generally come first.

If other decorators (parameter or class/method/setter) don't need to see that default value, then you should prefer the native default parameter value syntax in the function declaration. In TypeScript, you'll want to use both to get the appropriate typing for the method (but note that the value declared in the function signature will actually be ignored).

class Cls {
  // The decorator can see an `undefined` value
  @parameters(A)
  method1(param = -1) {}

  // The decorator will never see an `undefined` value
  @parameters([defaultValue(-1), A])
  method(param) {}
}

@optional()

The optional parameter decorator allows only applying a set of parameter decorators to argument values that aren't undefined, i.e. when an optional parameter is not omitted.

class Cls {
  @parameters(optional(A, B))
  method(param) {}
}

// The A and B decorators won't be called
new Cls().method();

// The A and B decorators will be called with the 42 value
new Cls().method(42);

TypeScript

Type inference should work in most cases, infering e.g. the method signature the decorator can be applied to from the parameter decorators (inference taking into account the parameter types of course, but also restrictions on the annotated method: its name, or whether it must static and/or private; as well as the containing class' shape, inferred from the decorators' context parameter). There are exceptions though, notably as soon as a parameter decorator has overloads (due to a design limitation of TypeScript in this case). To cope for those cases, the exported functions have overloads designed for explicit typing. You must then pass parameter types as type arguments, and can also pass the containing class' shape and method description as additional type arguments to check that the parameter decorators are used correctly.

class Cls {
  @parameters<[number, boolean, string]>(A, B, C)
  fn(a: number, b: boolean, c: string) {}

  @parameters<[number, boolean], string>(A, B, [true, C])
  variadic(a: number, b: boolean, ...rest: string[]) {}

  @parameter<string>(C)
  set prop(value: string) {}

  // A "full" declaration could be:
  @parameters<
    [number], // ← non-variadic parameters
    string, // ← rest parameter
    Cls, // ← containing class
    // ↓ method description
    { kind: "method"; name: "m"; private: false; static: false }
  >(A, [true, C])
  m(a: number, ...rest: string[]) {}
}