microsoft / microsoft/TypeScript

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

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

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

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

説明

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.

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

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

はじめの一歩

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

調査の方向性

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

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

評価

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

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

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