17:43
<rbuckton>

I was looking at the outline for parameter decorators mentioned here: https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#parameter-decorators-and-annotations, and was thinking about the shape of the context object. I think there are a few things we could add aside from kind:

interface ParameterDecoratorContext {
  kind: "parameter";
  index: number; // ordinal position of parameter
  name?: string; // name if an Identifier, `undefined` if a binding pattern
  rest: boolean; // indicates a rest parameter (i.e., `...`)
  parent:
    | {
        kind: "function";
        name?: string;
      }
    | {
        kind: "method" | "getter" | "setter";
        name: string | symbol;
        private: boolean;
        static: boolean;
        parent: // may be other parents in the future such as `struct`, `object`, etc.
          | {
              kind: "class";
              name?: string;
            }
      };
  // phase: "function" runs initializers at the start of the function body
  addInitializer(cb: () => unknown, phase?: "class" | "static" | "instance" | "function"): void;
}

The above also incorporates the parent context idea from https://github.com/tc39/proposal-decorators/issues/466

17:46
<rbuckton>
TS parameter decorators get the parameter index which is necessary for DI, RTTI, and RTTC, so that seems a minimum requirement for a parameter context.
18:41
<Mathieu Hofman>
index and a way to get the context / add an initializer to the method/function so that the parameter and function/method decorators can cooperate would be my requirements
23:35
<rbuckton>
I imagine "add an initializer" would match the behavior already proposed in EXTENSIONS.md and be somewhat similar to fields.
23:36
<rbuckton>
We might need to bifurcate ParameterDecoratorContext into kind: "parameter" and kind: "rest-parameter" (as opposed to a rest: boolean property on the context), because rest parameters can't have initializers.
23:38
<rbuckton>
I'm not sure what you mean by "get the context" however. Would that be similar to the opaque metadata context object proposal?
23:40
<Mathieu Hofman>
But you should still be able to add an initializer to the function/method definition, no? so it'd just be a runtime error to add an initializer to the rest param?
23:41
<Mathieu Hofman>
Right, I was referring to the opaque metadata, be able to reference the opaque object of the function/method
23:44
<Mathieu Hofman>

As I mentioned, I'm mostly interested in runtime checks, and would want to be able to express things like

const foo = (@string name, @array(number) ...values) => {}
23:54
<Mathieu Hofman>

But also be able to add runtime metadata so that I can do things like:

import { remotable, awaited } from 'rpc-lib';

const foo = remotable({
  foo: (@awaited thing) => {
    if (myCollection.has(thing)) {
      ...
    } else {
      ...
    }
  }
});

Where the remotable helper (which could be written as an object literal decorator) would be able to get the annotations for the foo method on the object it received, and (to really simplify) build a new object with a new foo method that will implicitly await on the first argument.