YYTypeScript#5「TSの好きな機能って何？」「enumは避けるべきか」「TSを選んだ理由を教えて」「業務で犯した型がらみの失敗談」「ソースマップも含めてnpm publishすべき？」「関数で書く派ですか？クラスで書く派ですか？」

これは2019年10月18日に開催したTypeScriptイベント[YYTypeScript#5]のイベントレポートです。

[YYTypeScript#5]: https://yyts.connpass.com/event/149065/
[YYTypeScript]: https://yyts.connpass.com/

[YYTypeScript]は一言で「TypeScripterの部室」です。発表者の話を聞く「一方向的な勉強会」とは真逆で、TypeScriptについて、雑に・ゆるく・ワイワイ話しながらTypeScripter同士の交流を深める「双方向的な座談会」の形式になります。集まった人たちで「今日話たいこと」「聞きたいこと」をいくつか挙げていき、それをテーマに雑談していきます。

__今回の配信動画__

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">YYTypeScriptの収録動画がアップされました！ <a href="https://t.co/XJP488vgkK">https://t.co/XJP488vgkK</a></p>&mdash; YYTypeScript (@yytypescript) <a href="https://twitter.com/yytypescript/status/1185135015455272960?ref_src=twsrc%5Etfw">October 18, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

__過去回の配信動画__ → [YouTubeプレイリスト「YYTypeScript」](https://www.youtube.com/playlist?list=PLpOeTEye3Bg4N8f7GSaeqM0p2dcdiZHv_)
__前回__ →  [YYTypeScript#4「axiosとfetchの違いが知りたい」「初心者だがCLIツールを作りたい。どう始めるべき？」「Vue 3.0で何が変わるのか？」「デメテルの法則を満たさないコードがだめな理由」「サーバサイドフレームワークを知りたい」「ライブラリの型定義が残念なときの対処法を教えて」「Null Object PatternはTypeScript的にどうなのか？」 - Qiita](https://qiita.com/suin/items/63d3ed74ec2cc5cbfd6d)

## 雑談

### takepepeさんからのTSConf JP CFP募集のお知らせ

![slack-imgs.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/72c11c09-00af-5c9e-c9a9-1b3344402345.jpeg)


* 2020年2月22日に開催される[TSConf JP](https://www.tsconf.jp/)のCFP(発表者)を募集中。
* 締め切り: 2019年11月30日
* 申込先: [TSConf JP 2020 Call for presentation](https://docs.google.com/forms/d/e/1FAIpQLSctNd72m4Flaa_qdue1KmBrNYJsDW57FeqIsjK6zZnqYv49kQ/viewform) 


### みなさんのTSの好きな機能ってなんですか？ (たけぺぺ)

* Universal JSという考え方
* Compiler API
* （ `ReturnType<T>` とかって何っていうんだっけ）
    * mapped type?
    * あ。それっぽいです。 Omit とか そこらへんの機能が好きです
* 型がついていると
    * 型駆動で書いたりしますよね
    * こんなメソッドが生えているとかドキュメントを見に行かなくていい
        * 補完が効いていいですよね。
            * 最近補完が遅い…＠IDEA
* Substructual Typing
    * 好きです！
    * オブジェクト指向しやすいと感じる
* コンパイルがないJSを書くのは変更とかが心理的に怖かったが、TSはそれがないのでいい
* もともとJSだったコードを徐々に置き換えていける
    * 動的言語の上に増設した言語なのでそういうことができる
    * 懐の広さがある。いろんなコンテキストで受け入れられたのかなと思う。
    * 最近Rust書いてるけど、TSって柔らかいんだなと感じました。
* typescriptでは any が好きです。
    * ガチガチの型システムじゃなくてチームや状況に応じて any っていう選択ができるっていうのが好きです

### みんなが今興味のある機能を知りたい (たけぺぺ)

* コンパイラAPIを掘り下げてちゃんと使えるようになりたい。
    * ドキュメントが少なくて、takepepeさんの著書くらいしかない
* tsconfig／コンパイラ周りのオプション
    * 色々増えてる部分とか使いこなしてないので
* optional chain
    * 3.7 beta でしたっけね
    * union typeでundefinedになる
* EitherとかMaybeがあってほしい
    * 自分で作る感じ。
    * 標準であるといいなと思う。
    * ElmとかPureScriptにいくしか……
        * Elmまでは行きたくない……
    * `_({}).hoge().filter().find().value()` みたいな感じで値ない場合とかに対応させてたことがあるかも？
        *  （lodash推しみたいな感じで申し訳ない...）
    * Ramdaみたいなやつほしい
    * https://github.com/gcanti/fp-ts とか有ります
        * [gcanti/fp-ts: Functional programming in TypeScript](https://github.com/gcanti/fp-ts)
* Compiler API
    * 三種の型パズル
        * DeclarationMerging
        * ConditionalType
        * CompilerAPI

### TypeScript特有の機能であるenumとnamespaceなど使ってますか？ (なかむら)

個人的にはあんまり使いたくないと思うけど、業務で使ってる人がいたら話したい。
TS特有というかは、JSのコードに大きな影響を及ぼす機能。
Flowから来たので、書いているコードとJSコードの乖離が大きいのに違和感がある。

・・・

* enumはstring引数に渡せるのが嫌だった
    * なので、クラス定数にした
* enum, namespaceはユースケース的に使うシーンがなかった
* namespaceはimport/exportを含まないWebライブラリを作るときに使いました
    * モジュールの代わりです
* JavaScriptの機能から外れるのが嫌
* 大規模な現場でバックエンドがJava
    * Javaにはenumがあるので、そのノリで使ってるところはある。
* 私的にはenumはTypeScriptに限らず使いづらい(から、使わない。)

### TypeScript 3.6のyield (やました)

yieldが細かい型指定が可能に。
Promiseが返せなくなって困っている。

```typescript
await value as Promise<T> // => T
yield value as Promise<T> // => TS3.6からコンパイルが通らなくなった

const promise: Promise<number> = Promise.resolve(1);
const num: 1 = await promise;
const num: undefined = yield promise; // 3.5の振る舞い
yield promise; // ts compiler 怒る :(
```

redux-observable で起動時の処理はこんな感じにかいています（合ってるかわからないけど）

```typescript
export const fooEpic: Epic = action$ =>
  action$.pipe(
    startWith(null),
    take(1),
    mergeMap(() => {
      // ...
    })
  );

```

### TypeScriptをなぜ使うべきなのか、プロの皆様に改めて聞いてみたい (れおりん)

なぜTypeScriptを選んだのか？

バックエンドをTS+Nodeで書くのってあんまりまだ聞かないが、むいているのかどうなのか？

・・・

* TypeScriptはデファクトスタンダードじゃないですか？
    * 選ばない手はないと感じてて。
        * ある程度業務とかで使うんだったら、jsdocなどで結局ドキュメントを用意しないといけない
            * TSだとその手間がない。
        * jsだと辛くなるのが目に見えてるから。かな？
* 導入コストがあると思うがどうですか？
* 枯れていないと感じてて、バージョンアップ
* 2019年のStackOverflowの統計、JSプロジェクトの20%くらいがTSという統計
    * 無くなっちゃうと嫌じゃないですか。
    * FlowやCoffeeScriptみたいに廃れると辛い。
        * TypeScriptがそうなるリスクはゼロじゃない
        * でもそうならないように配慮していると感じられる
            * ECMAScript準拠なので、型を外せばJSという安心化がCoffeeScriptとは違う
        * もし廃れるとしても、マイグレーションツールを誰か作りそう
            * Compiler APIはその手助けになるはず
        * typescriptがなくなるリスクよりも、jsで書いて開発が遅いとかを比べたときに、現状ではtypescriptを選択したほうがメリットのほうがでかい気がしてます(チーム等によるとは思いますが)
* 時代によって便利なものを使えばという考え
* リファクタのしやすさ、型が守ってくれるというところ。
* もともとPHPを使っていたが、チーム開発だと、動的型付けは本当はどんな型なのか不安になるから。

### 業務での型がらみの失敗談を聞きたい (たけぺぺ)

* 本書いているときにサンプルコードを書いていた
    * implicitAnyをfalseにしているのを忘れていた
    * なぜか型推論が効かなかったのでハマった
* DBからとってきたデータが`BigInt`なのに`number`型で書いてた。(正解は `string`)
    * コンパイルも通っていた。
    * 型がついていると安心してしまう
    * 実行時は分からない。
    * IOまわりはあるある。
    * 実行時に型が消え去るのが最初は直感的でない。
        * 初学者にはわりと最初のほうに言ってあげたほうがいいと思う。
        * 実行時型消去が起きる言語は多いと思うが。
* static メソッドが書かれたクラスからinterfaceきりだそうとしたけど、interfaceではstatic メソッドは素直には書けなくて、static メソッドはやっぱり極力避ける方向が良いなーって最近なってます。


### これ作ったらおもしろいっていうやつ何かあれば知りたい (たけぺぺ)

* Compiler APIを使うとstring literalを合成できる
* Lookup 
    * [keyof and Lookup Types in TypeScript — Marius Schulz](https://mariusschulz.com/blog/keyof-and-lookup-types-in-typescript)

```typescript
function prop<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}
```

* [vuex-guardian1 on Vimeo](https://vimeo.com/365567093)の5:00ごろのLookupタイプの実演
* generics 難しくて、generics 問題百本ノック、みたいのほしいです！(読む分にはなんとなく読めても、いざ書こうとしたときに書けないから、問題がほしい!)(vivid_muimui)
    * Arrayから始めると分かりやすい(`T[]`を`Array<T>`とかけることに気づくと早い)
    * 構えすぎているのかもしれない？
* Compiler APIを使って、DIしてくれるDIコンテナ

### VueやReactとTypeScriptの相性が最近良くなってきていると聞いたが (しんのき)

* Vueはちょっと前までTS辛いという話を聞いてたが、最近はあんまり聞かない気がする
    * VSCode上ではtemplateで型が効くようにはなる。
        * [Vue テンプレート内の式の型チェックと解析ができるまで | Web 猫](https://katashin.info/2019/04/28/261)
    * TypeScriptが辛かったのは、IDEによる補完機能がない時代だった頃のみかなーと思う感じ。今は補完機能が充実してるのでツラミより強みの方が多い。
* 最近はフレームワーク側からもTSをサポートする動きが強くなってきている
    * ボイラープレートにTSが用意されている。
* AngularはもともとTSなのでサポートがしっかりしている
    * Compiler APIも駆使してる
* Vue 3.0、JSXをデフォルトで対応する
* Vueのアイデンティティが型のために脅かされている？
    * あのワンファイルでできるので差別化してたのに
    * それ、Reactで良くねってなる？
* VueはJSで、ReactはTSっていう棲み分けができたら良かったのにね

### TypeScriptをJSエンジニア以外にも広めたい (やました)

伝道師になりたい。
これだったらTypeScriptが最強だ、というの得て帰りたいと思った。

・・・

* JavaScriptをベースにした言語なのでJSを知らないとだめだと思う
* TypeScriptからはじめましたって人はあんまり聞かないが
    * 増えてきているとは思う。
    * フレームワークがTSだとか現場がTSだとか
    * denoが大当たりしたら、TSネイティブの人ががっと増えるかも？
* source-map で js知らなくてもいけてしまう人もいそうって思ったけどどうなんでしょ？

### TS製のnpmパッケージを公開するとき、ソースコードも含めるべき？ (すいん)

TypeScript製のNodeモジュールをnpm publishするとき、コンパイル後のjsとd.tsだけにするべきか、それに加えてソースマップとTSのソースコードも含めるべきか、正解が分からないので教えて偉い人！

--sourceMap=true --inlineSources=trueにして.mapがあればソースコードはいらない？

・・・

* 何も考えずに全てpublishしてる
* 容量を減らすために、jsとd.tsだけにしている人もいる。
* デバッガビリティを上げたほうがいい(ソースも含める)
    * IDEのコードジャンプで飛べるほうがいい。

### 関数で書くか？クラスで書くか？ (すいん)

JavaScriptって、古くから関数型で書けるし、class構文が加わってからクラスも書きやすくなったわけだけど、みんなどのくらいの割合でclassを使ってるのか気になる。関数で書けるところもできるだけclassにするのか、関数とclassを使い分けているのか、できるだけ関数だけで書くようにしているのか。

```javascript
const createFoo = (state) => (args) => { /* do something */ }

class Bar {
    constructor(state) {}
      doSomething(args) { /* do something */ }
}

const foo = createFoo({ /* props */ })
foo(args)

const bar = new Bar({ /* props */ })
bar.doSomething(args)
```

皆さんの好みやベストプラクティスがあれば知らいたい

・・・

* class で書くケース
    * extends ReactComponent するようなとき
* class を使わないケース
    * thisに不安があるとき？といえば良いのか…？
* 関数で書くケース
    * instanceを意識せずmethod呼びたいような形の時

・・・

* 使い分けますね。
    * 状態を持ちたかったり、オブジェクト指向で書きたいときはclass。
    * 状態を持ちたくなかったりするときは関数で書くようにしている。
* 個人的にはクラスを定義してインスタンスを複数使うというユースケースが無い
    * むしろシングルトンをさって作って、さっと使うケースが多いので、関数をよく使う
* クリーンアーキテクチャやってるのでクラス使ってます
* Reactやってるとクラスに触れる機会が減った。
    * hookがあるので。
    * 公式で関数をおすすめしているので。
* フロントとバックエンドで違うと思う。文脈によるんじゃ？
    * バックエンドでドメインモデルを作るときとか。
    * フロントエンドは状態持ちたくない
    * バックエンドは状態持ちたい
* pipeline operatorのstageが進めば、関数派が加速するかも。


### 雑談開始前の雑談

#### Compiler API

* 型情報からモックデータを作るというのをやってみたが、うまく行かなかった。
* 型エイリアスが指す型は取れるけど、その先の型はとれないところでハマった。
* Compiler APIはドキュメントがまともに無いですよね。
* コンパイラのソースコード読んだら巨大すぎた。
    * Transformerあたりが魔界。
* ちゃんとドキュメント書いてないってことは、ステーブルじゃない？
    * どうなんですかね。
    * 実装に依存したコード書くと壊れるんじゃないかと心配。

## 参加してよかったこと(参加者の感想)

* expressのtsconfigはみんな手書きしてるんだなーと再確認できた。YYは楽しいよね。
* 技術のことでワイワイやるの楽しいですね！
* TypeScriptに関する知識量の深い人が参加されていて面白かった！
* 今まで話したことのないエンジニアのみなさんに会えた
* 自分より詳しい人がいっぱいいる！
* 自分が感じていることTypeScriptの問題とかを他の人も同じように問題と感じてると思えた。
* 新しい単語や知らない事を知れた


## YYTypeScriptは毎週やってます

YYTypeScriptについてワイワイ話したい方は、[YYTypeScriptのイベント情報](https://yyts.connpass.com/)をチェックしてみて下さい。

以上、YYTypeScriptのレポートでした。次回もワイワイやっていきたいと思います！ では、また来週！