Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScript の便利な型変形を なんとかして Scala.js で使う / Emulating TypeScript Utility Types in ScalaJS

TypeScript の便利な型変形を なんとかして Scala.js で使う / Emulating TypeScript Utility Types in ScalaJS

TATSUNO Yasuhiro

April 17, 2020
Tweet

More Decks by TATSUNO Yasuhiro

Other Decks in Programming

Transcript

  1. TypeScript の便利な型変形を
    なんとかして Scala.js で使う
    Tatsuno | exoego | 2020-04-16 | #typefesta

    View Slide

  2. 自己紹介
    長野県から参加してます
    Scala.js で GUI や AWS Lambda を
    書いて暮らしてます
    exoego exoego

    View Slide

  3. 今日言いたいこと3つ
    TypeScript には「型から型を作る関数」みたいな型、
    Mapped Type があります
    Scala(.js) ではマクロで型を生成したり加工できます
    Mapped Type を Scala マクロでエミュレーションし
    てみたが微妙なので、Scala 強い人たすけて!

    View Slide

  4. JS (JavaScript) が使われる場所多い
    Web やスマホアプリ、そのサーバー
    Web ブラウザの拡張
    Google Apps Script、Office Scripts
    PC アプリ(electron)

    View Slide

  5. でも JS はあまり書きたくない
    動的型付け言語なので、
    • 数値渡すところに文字列渡しちゃったり
    • Object 型のキー名を TYPO しちゃったり
    動かしてもなかなか気づけなくて時間を浪費

    View Slide

  6. そこで静的型付け Alt-JS (JS 代替言語)
    Haskell
    Elm
    OCaml
    Reason
    F#
    Fable
    Scala
    Scala.js
    使い慣れた言語、ツールセットで、
    JS をターゲットに開発できます
    元言語:
    Alt-JS:

    View Slide

  7. 型システムなど Scala 言語機能が使える
    • パターンマッチ
    • for内包表記
    • 既存の型に安全にメソッドを追加
    • 継承関係がなくても型が満たすべき制約を書ける(型クラス)
    • マクロでコードを自動生成(型プロバイダーなど)
    Scala ライブラリがけっこう使える
    Scala 対応 IDE/エディタで快適に開発
    Scala.js ⇔ JS 相互呼出できる
    Scala.js の特徴

    View Slide

  8. JS コードを型安全に呼ぶには
    開発では様々な外部の JS コードを使う
    • ランタイムの API: Web ブラウザ、Node.js…
    • フレームワーク: React、Vue、Angular …
    • 開発キット: Google Apps Script、Kintone、AWS…
    幸い、Alt-JS 言語には、こうした外部の JS に型定義
    をつけて、型安全に呼び出せる仕組みが結構ある

    View Slide

  9. 型定義の例 (Scala.js)

    View Slide

  10. こんな型定義を
    メンテするのは大変
    そこで…

    View Slide

  11. 本日も何度か出てきた、静的型付け Alt-JS
    巨大なコミュニティが多数の JS ライブラリに TS 用
    型定義を整備している
    最近では、ライブラリ本体が型定義を提供したり、
    本体が TS で開発される事例も増えてきている

    View Slide

  12. 巨人(TypeScript)の肩に乗れ
    TypeScript 用型定義を別の言語に変換するツールを
    使えば、複雑な型定義を書く手間を大きく削減 !!!!
    Scala.js https://scalablytyped.org
    https://www.exoego.net/scala-js-ts-importer
    Fable https://github.com/fable-compiler/ts2fable
    Reason https://github.com/cristianoc/genType

    View Slide

  13. ブラウザで試せます。★付けたり issue いただけると嬉しい
    https://www.exoego.net/scala-js-ts-importer

    View Slide

  14. しかし
    そう簡単には
    いかなかった!!

    View Slide

  15. TypeScript の
    型システムはヤバい…

    View Slide

  16. https://www.typescriptlang.org/docs/handbook/utility-types.html
    “ TypeScript は、よくある
    型変形 (type transformation)
    を手助けするいくつかの
    便利な型を提供します ”

    View Slide

  17. TypeScript の型システムでは
    型を別の型に変形(型から別な型を作成)
    する関数のような型を定義できます。
    このように作られた型を TypeScript では
    Mapped Type と呼ぶようです。
    (TS詳しくないので間違ってたら教えてください)

    View Slide

  18. 1. Partial
    T のプロパティを省略可能にする
    title を省略
    使用箇所
    以降のコード片は
    typescriptlang.org より引用

    View Slide

  19. 2. Readonly
    T のプロパティを読取専用にする
    再代入をエラーに
    使用箇所

    View Slide

  20. 3. Pick
    T から プロパティ K だけ残した型を作る
    使用箇所
    title と completed は
    元の Todo から引き継いでる
    リテラル型(プロパティ名)
    のユニオン型

    View Slide

  21. 4. Exclude
    U に代入可能なプロパティを T から除いた型を作る

    View Slide

  22. 5. keyof T
    keyof オペレータは、T のプロパティの集合を返す
    これまでの型変形のいくつかは
    keyof を活用。このように作られ
    た型が Mapped type

    View Slide

  23. これで React のこ~んな型が
    完全に理解できますね…!?

    View Slide

  24. さきほど Alt-JS の型定義変換ツールを紹介しましたが
    型変形/Mapped Type って
    他言語の型システムに
    どう対応させればいいの?

    View Slide

  25. Scala.js で
    やってみよう

    View Slide

  26. 戦略
    Scala 2 には型変形 / Mapped Type 相当はないが…
    マクロで AST を変形して型にプロパティを追加し
    たり、新しい型を生成したりできる !!
    Scala マクロ作る勉強のネタにやってみよう !!

    View Slide

  27. アノテーション
    マクロ
    コンパイル後

    View Slide

  28. アノテーション
    マクロ
    コンパイル後
    除外

    View Slide

  29. やってみた感想
    マクロおもしろいけど、Mapped Type の完全再現は
    ムリそうな気がしてます…
    https://github.com/exoego/scalajs-util-types で開発
    してるので、使ってみたい人、改良してみたい方は
    おチカラを…!!!
    Scala 言語機能にも Mapped Type っぽいの欲しい !!!
    JS 関係なく便利そうです

    View Slide

  30. 今日言いたいこと3つ
    TypeScript には「型から型を作る関数」みたいな型、
    Mapped Type があります
    Scala(.js) ではマクロで型を生成したり加工できます
    Mapped Type を Scala マクロでエミュレーションし
    てみたが微妙なので、Scala 強い人たすけて!

    View Slide

  31. Scala.js は
    覚悟があればいいぞ

    View Slide