Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

型定義の例 (Scala.js)

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

巨人(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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Scala.js で やってみよう

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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