YYTypeScript#2「トランスパイル後のJSのパフォーマンス」「npmモジュールの信頼性、どう担保してる？」「コンパイルが遅い」「みんなのtslintの設定とかTipsを教えて」「オブジェクトの構築と実行について」

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

[YYTypeScript#2]: https://yyts.connpass.com/event/144568/
[YYTypeScript]: https://yyts.connpass.com/

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

__今回の配信動画__

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">YYTypeScriptの収録動画がアップされました！ <a href="https://t.co/8HqVa2SZN2">https://t.co/8HqVa2SZN2</a></p>&mdash; YYTypeScript (@yytypescript) <a href="https://twitter.com/yytypescript/status/1177574943548039169?ref_src=twsrc%5Etfw">September 27, 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#1「JavaScriptを知らない人がTypeScriptを学ぶ方法を知りたい」「TypeScript初心者がどうやって勉強すると効率がいいか？」「なぜTSが選ばれるのか？」「PHPと比べて、サーバサイドをTSで書くメリットは？」「TypeScriptのバックエンドのオススメフレームワークって？」「定義をinterfaceとtypeどっちで書いてる？」「JSで書かれたプロダクトのTS化ってどうしてる？ 」 - Qiita](https://qiita.com/suin/items/7116732f2ac5412cdb82)

## 雑談

### トランスパイル後のJSのパフォーマンスが気になる (ましろ)

TypeScript実はこう書くとJSになったときパフォーマンスが落ちるなどあれば知りたい。

・・・

* 気にして書いてるひといます？
    * あんまり気にしてないかな
* async/awaitをES5にコンパイルすると、結構ごちゃごちゃしたコードが増えるのは気になる。
* polyfill的なコードが増えると遅くなっちゃう気はする。
* あんまりトランスパイルで遅くなったって話は聞いたことが無い気がします。
* なるべく新し目のtargetにしてあげたほうが良さそう。
* だいたいlodash使ってるんですけど、map/filterとかでchainする時、量が多そうだったらreduceでまとめる。ってのは考えてますが、jsの世界の話ですね。。
    * map/filter書く時にlodash使います？ `Array.prototype.map` の方を好んで使ってます
    * _(arr|obj).map().filter().value() が好きで。。
        * ひゃー、知りませんでした・・・ [こんな感じ](https://qiita.com/kurararara/items/fb470ea71e59cd0371d4) ですかね
            * ですです
        * 個人的には、それでも `[].filter(() => _).map(() => _)` の方が趣味ですねー
        * obj側との行き来？とかで強い？ような気がしてるんですけど、もう足りてますかねー
* コンパイル後のコードって見てます？
    * 変わったコードを書いたときに気になって見ることはあるが。
    * あんまり見ない。ふと気になって見る程度。
    * あまり見ない構文／ts独自の構文とかどうなってるかな？って見るけど普段見ない
        * interface 消えてるかな？とか
    * へー。ほとんど見たことないなぁ…
    * Enumとか見ると、ちょっと面白い。 `Enum["hoge"]` と `Enum[0]` どちらでも参照できるトリック。
    * トランスパイル後のコード気になるときは、 [公式のplayground](https://www.typescriptlang.org/play/) が便利です。
* [10++ TypeScript Pro tips/patterns with (or without) React](https://medium.com/@martin_hotell/10-typescript-pro-tips-patterns-with-or-without-react-5799488d6680)
    * const Enumはいいの？よくないの？
* 僕はES2015+互換性の低めな機能は避けてたりします
    * Babelでトランスパイル出来なかったりとかも…。
    * polyfillで解決できないパターンとかがあるのかな(polyfill使ってないので知らないのですが)
* IE11で動かしたいという業務システムもあって、ES5を選びがちだったりします。
    * EdgeにIE11モードがついたらしい
    * IE11+Windows10は2029年まで……
    * Chromeになっていってほしい
    * そういう意味だとSafariが遅れ気味になってる感じもする
    * ブラウザ使わずElectronで業務システムってだめなのかなー

### オブジェクトの構築と実行について (かきうち)

オブジェクトに構築と実行の段階があるという話を聞いたが、もっと詳しく聞きたい。

・・・


#### 完全コンストラクタ　

```typescript
// 構築フェーズ
const obj = new ClassFoo(
    new Foo(),
    new Hoge(new Test()),
)

// 実行フェーズ
obj.doSomething()
```

#### 不完全コンストラクタ

```typescript
// 構築フェーズ
const obj = new ClassFoo(
    new Foo(),
)

// 実行フェーズ
obj.setHoge(new Hoge(new Test())
obj.doSomething()
```

```typescript
// 不完全コンストラクタなお家
class IncompleteHouse {
    private floor: Floor | null = null
    private bed: Bed | null = null
    
    setFloor(f: Floor) {
        this.floor = f
    }
    setBed(b: Bed) {
        this.bed = b
    }
    
    build() {
        return this.floor.set(this.bed)
    }
}

const incompHouse = new IncompleteHouse()

incompHouse.setBed(new Bed())
incompHouse.build() // this.floor.setでぬるぽ（床がないのにベッドを置くな）

// 完全コンストラクタなお家
class CompleteHouse {
    // 実際に作る時は、readonly付けておくの推奨です
    private bed: Bed | null = null

    constructor(private floor: Floor) { }

    setBed(bed: Bed) {
        this.bed = bed // 今回はmutableにしちゃいます（サクッと書くのを優先して・・・）
    }
    
    build() {
        return this.floor.set(this.bed) // Floor#setはnull許容に(ry
    }
}
const compHouse = new CompleteHouse(new Floor())

compHouse.build() // コンストラクタでfloorの存在が保証されている
```


* クラスを使わない（過激派）

* newするのを最初に作りきっちゃう。
* 構造を全部作りきってから、実行すると見通しがいい。
* 不完全コンストラクタはやめましょう、みたいなお話ですかね。
    * 不完全コンストラクタ「newした後、setHogeで値を設定してからdoHogeしないと死にます」
        * 構造の組み立てが、newとsetHogeの2段階に別れてる、的な
        * なるほど！
    * SOLID原則のI（インターフェース分離原則）的にあかんパターンですかね
    * 複雑な感じになってる感じがあるかなー（責務で、さらにクラスや関数を分離した方がいいパターンかも？）
* 変動する値は実行時に決めるしかない
* 不完全コンストラクタにならざるを得ない構造の場合、`build` で、いっそ、別オブジェクト（完全になったオブジェクト）を返すとかどうだろう？不完全コンストラクタは完全コンストラクタを作る、ビルダパターンに責務を限定しちゃって、実際の動きは完全コンストラクタに任せるみたいな二段構え作戦とか

### npmモジュールの信頼性ってどう担保、チェックしてる？ (すいん)

マルウェアが入ってたり、攻撃コードが混入されることへの予防策を知りたい。
過去にnpmモジュールを乗っ取り、ビットコインウォレットを狙う事件があった。[2018/11/27に判明したnpmパッケージ乗っ取りについて - Qiita](https://qiita.com/azs/items/b15bc456bee3a7892950)

最近サーバサイドでTSを使っているので怖い。

・・・

* [Auditing package dependencies for security vulnerabilities | npm Documentation](https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities)
    * `npm audit`コマンドで脆弱性のチェックができるっぽい。
    * CIに組み込んだらいいと思う。
        * おー、良さそう
    * [Securing your code | npm Documentation](https://docs.npmjs.com/packages-and-modules/securing-your-code)
    * 既知の脆弱性だと見つけられる、未知だと厳しい。
* denoだと通信していいURLを制限できたりする。
    * そういう意味だとDockerとか、インフラで制限したほうがいい。
    * インフラ、ネットワークも含めて多方面での防護（多層防御）をした方がいい。
* みんなどうやってパッケージ見極めている？
    * 直接依存しているパッケージは見るようにしているが、
    * 依存しているパッケージが依存しているパッケージまでには目が行かない。
* [npm | Enterprise](https://www.npmjs.com/products/enterprise)
    * パッケージをチェックしてくれる機能があるらしい。
* そういや最近GitHubにyarn.lockをcommitすると、（自分が直接依存してない）パッケージで古いやつが紛れてると、インセキュアじゃ！と言って勝手にPR出されたりするよね…
    * yarnの話とは違うけどgithubがsecurity-alertみたいなメール出してくれてますね
* 依存が少ないpackage使うと良かったりします？
    * 多いと、巻き添え的に何かしら喰らいやすい気はしてます
* npmのアカウントを2要素認証にしておくことで、npmアカウントの乗っ取りを防止する。
* 開発者のPGPのシグネチャがついていないパッケージは使わないこと

### babelでTS解析楽しい（erukiti） ﾘﾓｰﾄ

* https://github.com/noxtjs/gateway
    * 指定されたディレクトリ以下をbabelってエラー出なければTS型定義探して、それを元に動くDIコンテナみたいなやつ作った
    * https://github.com/noxtjs/gateway/blob/master/src/gateway/analysis-adapters.ts
    * babelでTypeScriptの型アノテーション typeAnnotation とか見たりしてる
* tscいじるよりbabelの方が慣れてる分扱いやすい(TSでもFlowでもいける)
* ちなみに、babelでTSの解析 + Module(require) hack してます
    * https://github.com/noxtjs/gateway/blob/master/src/module-hack.ts

### コンパイルが遅い。ts-nodeのオーバーヘッド。（interface の？） generics。promise経由のせいか若干推論がおかしかったこと。 (ゆた) ﾘﾓｰﾄ


#### コンパイルが遅い。

具体例が特にあるわけじゃないんですけど…自分のprojectがいま遅くなってきてて。
こういうプロジェクトは遅くなってきますよとかなにか知見があったら嬉しいです。

・・・

* 何行くらいですか？
    * githubで見たら105ファイル、行数は測るツールが手元にない

* ファイル数が多くなるとどうしようもないかも
* 自分のMacだと5分くらい。
* 2分くらい。
* 初回が遅いだけで、`--watch`をつけると差分は早い。
* `--incremental`ってどうなの？
    * [TypeScript 3.4のincrementalフラグを試す - Qiita](https://qiita.com/daishi/items/1b33f9c3d04f10a24f5b)
        * incremental 確か試しました。出力をwebpackに食わせてたんですけど日時で検知してるのかwepack側がおそくなってしまった記憶です
            * webpack側でts-loaderにするとか色々分けるとか考える余地はあるのでそのうち試します。。
                * 構造を変えるパターンのお話聞こえました。その余地はあるかんじです。
        * 今は --watch で、 webpackに食わせてます。
* コンパイルのボトルネックを分析するツールって無いんですか？
* jestも、ts-jest使うと遅いですよねー。babel-jestに乗り換えたら一気に快適になった。babel-node使うのありかも？？（型チェックはしなくなるけど）


#### ts-nodeのオーバーヘッド。

npm-run-scripts で task 管理してるんですけど、長いscriptはtsファイルに追いやって ts-node 経由で呼んでる。pre/post のチェーンで何度も ts-node が呼ばれることになるのでじゃっかん気になる。run-scripts の管理方法的な話とかも聞けたら嬉しい。

・・・

* ts-nodeは最初実行前にコンパイルする時間は気になります。
* ts-nodeが何回も呼ばれるのでそれを回避 > scriptのpre-post含めたシーケンスをすべてまとめてしまうって感じになりそう
* 遅い原因は、 ts-node 自体の起動時間、tsのコンパイルが入ると思うので。って感じです
* 現状何分とかの内容ではないですが、今後このままでよいのかな？という不安がある
* 1つのtsファイルを起点にするようにpackage.jsonのscripts定義を書き直すと安心？
    * ↑の `scriptのpre-post含めたシーケンスをすべてまとめてしまうって感じになりそう` ですかね
    * ですかね！ts-node実行の最初のオーバーヘッドが問題だとして、それが1回になれば問題になるほどではなくなるはず
    * npm-run-scripts で小さく管理しよう。っていう話もあるような。


#### （interface の？） genericsでうまく書けなかった 

やりたかったことはこんなの。
-> 推論がおかしかったのは別の話です（promiseの例は作れなかったです）

はい。genericsの書き方の話です。

```typescript
interface Action<IN, OUT> {
  (i: IN): OUT 
}

interface DAction<OUT> extends Action<string, OUT> {
}
```

最終的にはこうした。

```typescript
interface DAction {
  <OUT>(i:string): OUT;
}

```

```typescript
// こんな感じで普通に使えそうな気がしたけれど、こういう事ではない？
interface Action<IN, OUT> {
  (i: IN): OUT 
}

interface DAction<OUT> extends Action<string, OUT> {
}

const a: DAction<number> = (i: string) => parseInt(i, 10)

console.log(a('123'))
```

```typescript
// こうしたいのです
const b: number = a<number>("");
// 元のコードの例があまりよくないのかも
// あとさらにDActionをgenericsでラップしてるので
// そこら辺含めるとうまく伝えられていない感じがします。。
```



* Promiseの型推論、通常のresolveの型はgenericsで指定できるけど、rejectする型が指定出来なくて悲しみ
    * わかりみ
    * catch で as Hoge みたいに assertion しないと型が付いてくれない…
        * そうしてますね

### Linter と Formatter の設定Tips とか聞きたいです (tadashim) ﾘﾓｰﾄ

* どんな設定してますか？
    * フレームワークによってガラッと変わる気がする

* 最近、prettierだけ設定して、eslintはあまり真面目に考えてない…
    * React のときは、create-react-app で作られるヤツそのまんまで思考放棄
    * TypeScript 自体がある種の Linter だから型さえ真面目に書けばある程度linterサボれる気がしてる

* とりあえず↓が入ってた
```json:tslint.json
        "extends": [
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended",
        ],
```

* Angularのtslint使っていて、prettierを合わせて使ってる。
    * たまに衝突して辛い。
        * 設定同士の衝突系は、VSCodeとも衝突するからそれぞれの設定が面倒になってしまうのはありますね
    * prettierとの衝突回避↓

```json:tslint.json
  "extends": ["tslint:recommended", "tslint-plugin-prettier", "tslint-config-prettier"],
```

* [git commitしたときにTypeScriptコードを自動修正する方法(tslint, prettier, lint-staged使用) - Qiita](https://qiita.com/suin/items/ed6739dc1afb125c9b35)
    * suinおすすめ
* tslintは今後非推奨になっていくことが発表されてませんでしたっけ？
    * ですかねー。eslintのtypescript-eslintつかえーって
    * eslintに統合していく動き

tslintの今後:

8月　コアルール追加の終了
11月　機能追加の終了
来年1月　セキュリティを除く全ての変更を停止
来年12月　すべての変更を停止


* tslintからeslintへの以降は難しい？
    * わかりません

## その他の雑談

### 技術書典7

* [Node.js中級者を目指す - このすみ堂 - BOOTH](https://booth.pm/ja/items/1545887)
* [Effective React Hooks - 東京ラビットハウス - BOOTH](https://tk-rabbit-house.booth.pm/items/1477000)
* [TypeScriptとクリーンアーキテクチャで最高の開発者体験（DX） - 東京ラビットハウス - BOOTH](https://tk-rabbit-house.booth.pm/items/1576615)

### JSふわっと覚えてる人におすすめ

* [『JavaScript Primer: ECMAScript 2019時代のJavaScript入門書』](https://jsprimer.net/) - すでにプログラミング経験がある人が読むとJavaScriptの文法や機能を中心に学ぶことができる本。TypeScriptを書くにもJavaScriptの知識が必要不可欠なので、雰囲気でJSを書いてきた人やちゃんとおさらいしたい人におすすめ。ブラウザで無償で読める。

### TypeScript Meetup

* [【増枠】TypeScript meetup #3 - connpass](https://typescript-jp.connpass.com/event/146155/)
* 満員で抽選になってる。
* takepepeさんが発表するから参加したい。

### Nestって？

サーバサイドのフレームワーク。Angular使ってる人は使いやすいらしい。

### ngrxって？

Angularで使われている状態管理。

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

* いろんな知見が得られてよかったです
* incrementalフラグを知ることができて良かったです。
* オブジェクト指向の構築と実行について聞けたこと。
* リモートだけど参加している感がある
* セキュリティとか、あまり真面目に追いかけられてないので、これはやっておくべきだなーという気持ちに。
* いろんな話題があって面白かった。


## YYTypeScriptは毎週やってます

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

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