microsoft / microsoft/TypeScript

Ability to pick setter types (instead of getter types) in a mapped type

オープン
#60,162 コメント 3 件 リアクション 5 件 担当者 0 名 GitHub で見る

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

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

説明

🔍 Search Terms

typescript extract setter types mapped type

✅ Viability Checklist
⭐ Suggestion

(original thread on Discord)

This might be a request for a new utility type, or a new language feature, because there seems to be no way to do it with current language features currently:

Given this type:

class Foo {
  get foo(): number {...}
  set foo(v: 'foo' | 'bar' | number) {...}
}

We want to derive a type like this:

type Derived = PickWithSetterTypes<Foo>
// result:
// {foo: 'foo' | 'bar' | number}

There seems to be no way to implement PickWithSetterTypes in userland.

📃 Motivating Example

When writing class-based JSX components (for example, custom elements are written as classes), the JSX property types are setters, not getters.

In this JSX expression:

return <some-element foo={123} />

The foo prop is a setter, and it is setting the property on the custom element, it is not reading the property from the element.

So, when we define a class component, for example:

class SomeElement extends HTMLElement {
  get foo(): number {...}
  set foo(v: 'foo' | 'bar' | number) {...}

  someMethod() {... this method should not be included in JSX types ...}
}

customElements.define('some-element', SomeElement)

We need to pluck the properties that we want available in the JSX. For example, something along the lines of this:

declare module 'some-lib' {
  namespace JSX {
    interface IntrinsicElements {
      'some-element': Pick<SomeElement, 'foo'>
    }
  }
}

Now, the problem is, when we try to set a valid value for the property in JSX, it will not work:

return <some-element
  foo={'foo'} // Type Error: 'foo' is not assignable to number
/>

There should not be a type error, because the setter actually does accept the value 'foo'.

💻 Use Cases
  1. What do you want to use this for?
    • Any situations where the setter types need to be extracted, for example JSX props
  2. What shortcomings exist with current approaches?
    • it is impossible right now
  3. What workarounds are you using in the meantime?
    • Workarounds could include providing separate named properties that can be extracted with template string types, but it is very cumbersome
      class SomeElement extends HTMLElement {
        set foo(v: this['_set_foo']) {...}
        get foo(): number {...}
        
        /** do not use this property, it is for types only */
        _set_foo!: 'foo' | 'bar' | number
      }
      
      With this method, now a utility type can be written that can use template string types to extract the setter type from the non-setter dummy property type, something like this:
      type SomeElementJSXProps = JSXProps<SomeElement, 'fooBar' | 'foo'> // see linked playground below
      
      declare module 'react' {
          namespace JSX { interface IntrinsicElements { 'my-el': SomeElementJSXProps } }
      }
      
      TypeScript playground example

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

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

はじめの一歩

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

調査の方向性

リンクされた TypeScript Playground の例と、issue の mapped-type、getter/setter、JSX のシナリオから始めます。payload にはリポジトリのファイル、テスト、エントリーポイントが記載されていません。既存の getter および JSX の動作を維持しながら setter の型を抽出することを中心に設計と受け入れケースを定義し、その後、関連するコンパイラテストと実装領域を特定します。

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

評価

技術スタック
typescript
領域
compilers, developer-experience
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
28/100

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

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