Suggestion: ClassMethodDecoratorContext's name property could pick up Value["name"]

Aperta
#54,850 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
25/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
javascript, typescript
Ambito
compilers

Direzione di ricerca

Inizia con la definizione di ClassMethodDecoratorContext e confronta il tipo di nome condizionale proposto con la specifica ECMAScript Function.name. Usa il Playground collegato per verificare i risultati inferiti per i casi con nome e senza nome. Il lavoro è completo quando viene risolto se la modifica proposta a lib-definition è valida secondo la specifica.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Needs More Info

lib Update Request

Configuration Check

My compilation target is ESNext and my lib is the default.

Missing / Incorrect Definition

interface ClassMethodDecoratorContext<
    This = unknown,
    Value extends (this: This, ...args: any) => any = (this: This, ...args: any) => any,
> {
    // ...
    /** The name of the decorated class element. */
    readonly name: string | symbol;

    // ...

We could change the name field to: readonly name: Value extends { name: string } ? Value["name"] : (string | symbol);. Most of the time, Value["name"] is just string, so this would be a non-breaking change (if slightly less intuitive).

However, if I were to augment my method type definitions to have a name property, TypeScript could pick up on it:

Sample Code

export type NumberStringType = {
    repeatForward(s: string, n: number): string;
    repeatBack(n: number, s: string): string;
};

type NST_RF_raw = NumberStringType["repeatForward"]["name"]
//   ^? type NST_RF_raw = string

type MethodsOnlyType = {
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
  [key: string | number | symbol]: (...args: any[]) => any
}

type NamedMethodsOnlyType<T extends MethodsOnlyType> = {
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
  [Key in keyof T]: T[Key] & { name: Key }
}

type NST_RF_named = NamedMethodsOnlyType<NumberStringType>["repeatForward"]["name"];
//   ^? type NST_RF_named = "repeatForward"

type DefaultInferredName = ClassMethodDecoratorContext<
//   ^? type DefaultInferredName = string | symbol
  NumberStringType, NamedMethodsOnlyType<NumberStringType>["repeatForward"]
>["name"];

interface ClassMethodDecoratorContext_Named<
  This = unknown,
  Value extends (this: This, ...args: any) => any = (this: This, ...args: any) => any,
> {
  readonly name: Value extends { name: string } ? Value["name"] : (string | symbol);
}

type DirectName = ClassMethodDecoratorContext_Named<
//   ^? type Directname = "repeatForward"
  NumberStringType, NamedMethodsOnlyType<NumberStringType>["repeatForward"]
>["name"];

type InferredName = ClassMethodDecoratorContext_Named<
//   ^? type InferredName = string
  NumberStringType, NumberStringType["repeatForward"]
>["name"];

Obligatory Playground link

Motivation

I've been experimenting with method decorators for about a week now, to implement some aspect-oriented programming (or at least, my understanding of it). One facet I haven't yet cracked is removing the need for the method name on a decorator:

  class NST_Class extends NumberStringClass {
    @precondition<"repeatForward">(callForwardPre)
    repeatForward(s: string, n: number): string {
      return super.repeatForward(s, n);
    }
  }

Since the context has a name field of string | symbol type, I can't infer the name from that... I think.

I am perfectly willing to be wrong and have this whole ticket closed as invalid!

Documentation Link

The ECMAScript 2023 specification for Function.name says I'm possibly wrong here: it specifies the name field must be a string (specifically, "not a symbol"). This could be just a specification bug with the introduction of symbol keys, but I am not ready to assert that at this time.

Lingua principale
Go
Stelle
111k
Fork
14.4k
Merge medio
1g 19h
PR unite (30g)
117

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/TypeScript

Tutte le issue di microsoft/TypeScript

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.