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

オープン
#54,850 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
javascript, typescript
領域
compilers

調査の方向性

ClassMethodDecoratorContext の定義から始め、提案されている条件付き名前型を ECMAScript Function.name の仕様と比較します。リンクされている Playground を使って、名前付きの場合と名前なしの場合の推論結果を確認します。提案されている lib-definition の変更が仕様に照らして有効かどうかを解決できれば完了です。

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
Go
スター
111k
フォーク
14.4k
平均マージ
1日 19時間
マージ済み PR(30日)
117

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/TypeScript のほかの issue

microsoft/TypeScript の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。