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

Stranger Typings

Stranger Typings

NGK2017Bで発表したLT。

1. JSライブラリをScala.jsから使いやすくする型定義をラクに得る戦略
2. その戦略の障害となっている TypeScript の奇妙な型

の紹介。

TATSUNO Yasuhiro

December 03, 2017
Tweet

More Decks by TATSUNO Yasuhiro

Other Decks in Programming

Transcript

  1. @smogami 2017-12-02 #NGK2017B

    View Slide

  2. 冬の夜長に
    ストレンジャーシングス

    View Slide

  3. 話者: @smogami
    所属: JAWS-UG, FP in Scala読書会, 来栖川電算
    職歴: 製造業系SIer 6年→ベンチャー 1.5年
    業務: ScalaとAWSでSaaS開発

    View Slide

  4. 本日のお話
    1. JSに型をつけてScalaから呼ぶ
    2. TypeScriptというaltJSの変な型

    View Slide

  5. altJSって?
    • 今日何度目だ「JS書きたくない」
    • JSに代わる言語で書いたコードをJSに変換して、
    ブラウザやnodejsなどで動かす仕組み
    • JSにはない便利機能を使えたり、JSの嫌なところ
    を意識せず書けたりするのがメリット
    • 古くはGWT(JavaでAjaxアプリ開発)

    View Slide

  6. 色んなaltJS
    動的型付け
    • CoffeeScript
    • ClojureScript
    静的型付け
    • TypeScript
    • Haxe
    • Scala.js(私)
    • Elm
    • ocamljs
    名古屋で
    使われてる

    View Slide

  7. Scala.js採用してる理由
    1. 強力な型システムや言語機能
    2. JavaやScalaの人材と資産の活用
    3. JetBrains IDEの強力なサポート
    Scala/Scala.jsで製品開発・運用中

    View Slide

  8. TypeScriptやScala.jsなどの
    静的型付け系altJSの大きなメリット
    JSライブラリに型定義をつけることで
    • 型を間違えた引数を関数に与えたりすると、
    IDEやエディタがすぐにエラーを教えてくれる
    • オブジェクトが持つメソッドや属性を入力補完
    できて、すばやくミスなくコードを書ける
    Binding or Façade

    View Slide

  9. Scala.jsと型定義: 有名どころあり
    • jQuery, React, Vue, Angular
    • D3, Three.js, highcharts, Paper.js, Velocity.js…
    • Google Maps, YouTube, WebRTC, moment.js…
    • https://www.scala-js.org/libraries/facades.html
    に詳しい

    View Slide

  10. 静的型付け系altJSの悩みどころ
    • 有名ライブラリだと公式・コミュニティベースの
    型定義が充実してきたが…
    • マイナーライブラリの型定義作るコスト
    • メチャクチャなオーバーロードだらけの便利関数
    に型つけるつらさ
    型安全の恩恵を得るには型定義メンテの代償が必要

    View Slide

  11. できるだけラクに
    型定義が欲しい!!
    エンジニア三大美徳
    怠惰・短気・傲慢

    View Slide

  12. JSライブラリにTypeScript用の型定義が普及してきた
    巨人の肩に乗る

    View Slide

  13. JSライブラリにTypeScript用の型定義が普及してきた
    ↑をScala.js用に変換するツール by Scala.js開発者
    https://github.com/sjrd/scala-js-ts-importer
    巨人の肩に乗る

    View Slide

  14. JSライブラリにTypeScript用の型定義が普及してきた
    ↑をScala.js用に変換するツール by Scala.js開発者
    https://github.com/sjrd/scala-js-ts-importer
    ↑をブラウザで手軽に試せるようにしました(実演)
    http://exoego.net/scala-js-ts-importer/
    巨人の肩に乗る

    View Slide

  15. scala-js-ts-importerどうなの?
    • 完璧ではないが十分使える。これベースに、より
    Scalaらしく書けるラッパーを作ると生産性高い
    • TypeScriptとScalaの型システムは一致しないので、
    小一時間の手作業はどうしても必要
    • TSが「JSに型つけるためにがんばり過ぎ」な所は
    サポートが追いついていない
    ここを何とかしたらScala.jsの未来も明るい

    View Slide

  16. ほそぼそと改善が続いている
    Me

    View Slide

  17. scala-js-ts-importerハッカソン
    https://scala-tokai.connpass.com/event/72650/
    日時:明日 12/3 (日) 10:00~18:00
    場所:名古屋 来栖川電算, JR/地下鉄 鶴舞駅
    特典:フリードリンク、ピザ or 回らない寿司(宅配)
    現在参加者3名…興味湧いたらぜひ!!

    View Slide

  18. 時間があったら
    TypeScriptの奇妙な型

    View Slide

  19. こんなのどうやって
    Scala.jsに変換すれば
    いいんだ…

    View Slide

  20. 奇妙1. Literal type
    ある特定のリテラル値である、というような型。
    Scalaにも欲しい(Scala 3で入る予定がある)
    type EventName = "ready" | "click" | "submit"
    type TimeUnit = "day" | "hour" | "minute" | "s" | "ms"
    type HttpResponse = 100 | 200 | 404 | ...
    let name: EventName = "NGK" // error!!

    View Slide

  21. 奇妙2. Type Predicate
    Union type(A または B、 A | B)のいずれかである
    ことを表せる特別なbooleanみたいなもの
    function isFish(pet: Fish | Bird): pet is Fish {
    return (pet).swim !== undefined;
    }
    let pet = getSmallPet();
    if ((pet).swim) {
    (pet).swim();
    } else {
    (pet).fly();
    }
    if (isFish(pet)) {
    pet.swim();
    } else {
    pet.fly();
    }
    キャスト必要
    キャスト不要
    Type predicateを返すfunction=Type Guard

    View Slide

  22. 奇妙3. Index type
    オブジェクトの持つメンバーを型安全に参照できる。
    型TのIndex type=メンバー名のstring literal typeのunion
    interface Person {
    name: string;
    age: number;
    location: string;
    }
    type K1 = keyof Person; // "name" | "age" | "location"
    type K2 = keyof Person[]; // "length" | "push" | "pop" | "concat" | …

    View Slide

  23. 奇妙4. Indexed access type
    Index typeの双対(dual)。
    メンバーの型をメンバーの名前で参照できる
    type P1 = Person["name"]; // string
    type P2 = Person["name" | "age"]; // string | number
    type P3 = string["charAt"]; // (pos: number) => string
    type P4 = Person["foo"]; // error !!
    let myName: P1 = 30; // error!!

    View Slide

  24. 奇妙5. Mapped type
    Index typeとIndexed access typeを組み合わせることで
    型TのメンバーPを加工した型をシンプルに定義できる
    type Nullable = { [P in keyof T]: T[P] | null }
    type Partial = { [P in keyof T]?: T[P] }
    type Proxy = {
    get(): T;
    set(value: T): void;
    }
    type Proxify = {
    [P in keyof T]: Proxy;
    }

    View Slide

  25. まとめ
    • TypeScriptの型システムは、JavaScriptにとにかく型を
    つけようとがんばってる
    • TypeScript用の型定義をScala.js用に変換すると、比較
    的ラクに型定義を得られる
    • 明日のscala-js-ts-importerハッカソン来てね!
    https://scala-tokai.connpass.com/event/72650/
    • NetflixのStranger Thingsオススメ!

    View Slide

  26. 参考
    • TypeScriptの高度な型
    https://www.typescriptlang.org/docs/handbook/advance
    d-types.html
    • Scala.js用の型定義の代表例
    http://www.scala-js.org/libraries/facades.html
    • Scala.js用型定義を集めたサイト
    https://definitelyscala.com/

    View Slide