microsoft / microsoft/TypeScript

Proposal: support pathof along with current keyof

オープン
#20,423 コメント 25 件 リアクション 33 件 担当者 0 名 GitHub で見る

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

Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

Problem - What are users having difficulty with?

While using popular libraries for their day to day development needs, developers can find them disjoint from typesafe philosophy even if they do have the needed typings. This is true for frequently used libraries such as lodash and immutablejs that access or set properties via paths. It is up to the developers to to preserve typesafety by expressing complex types using the amazing power that typescript gives them. The only obstacle is the absence of a way to express the type that represnts legit object paths for a specific type.

Current state

We can currently do this only for shallow objects where paths can be simply expressed as the keys of a specific type.

Example Issue

In an effort to play with stricter typings for immutablejs map I created this tiny project :
https://github.com/agalazis/typed-map/
(as a side note my personal view is that immutable js map is not a conventional map that should be represented with map<keyType, valueType> since it represents a map that matches a specific type rather than just a key,value data structure as demonstarated in src/examples)

The type I created was just this (only playing with get and set):

export type TypedMap<T> = {
  get: <K extends keyof T >(k:K) => T[K];
  set: <K extends keyof T >(k:K, v:T[K]) => TypedMap<T>;
}

Simple enough, leveraging all the expressiveness of typescript.

Example usage of the proposed solution:

If I could replace keyof with pathof in order to express possible path strings and also used T[P] as the path type I would be able to completely cover this use-case :

export type TypedMap<T> = {
  get: <P extends pathof T >(p:P) => T[P];
  set: <P extends pathof T>(p:P, v:T[P]) => TypedMap<T>;
}

Possible usage in the following libraries:

  • lodash
  • immutable
  • ramda
  • anything built on top of them
Why bother since this does not involve facilitating any feature of ES standard?(and is somewhat an unconventional feature)
  1. We will be able to perform type-safe updates using existing js immutability libraries similar to what you can achieve in other languages (eg. skala lense).
  2. This feature complies with typescript goals:
  • Statically identify constructs that are likely to be errors.
  • Provide a structuring mechanism for larger pieces of code (the above-mentioned libraries are used every day in big projects imagine the chaos that can be created. Despite exhaustive unit testing, intellisense is a must ;) ).
  • Strike a balance between correctness and productivity.
  1. This feature improves compile time checks and sticks to the mindset of not having to deal with any runtime functionality
  2. There are no side effects in the generated js code
Alternatives

While digging further into the issue an alternative solution is to be able to spread keyof recursively. This will allow us to be creative and build our own solution as per:
https://github.com/Microsoft/TypeScript/issues/20423#issuecomment-349776005
The drawbacks of the alternative solution if doable are:

  • performance
  • lack of cyclic reference support
Implementation Suggestions

The optimal (if implemented in the language) would be to not compute the full nested object paths but only the paths used via pathof ie when declaring something as path of x just accept it as pathof x then when a value is assigned just validate it is pathOf x( the compiler could also have some sort of caching so that it doesn't recalculate paths).
This will also solve the issue with cyclic references since paths will be finite anw.

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

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

はじめの一歩

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

調査の方向性

まず、提案されている pathof 構文と issue にリンクされている typed-map の例を確認し、その後、参照されているコメントにある再帰的な keyof の代替案と比較してください。言語設計、循環参照の動作、コンパイル時のパス検証が解決され、受け入れられた場合にのみ issue は完了となります。

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

評価

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

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

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