YYTypeScript#4「axiosとfetchの違いが知りたい」「初心者だがCLIツールを作りたい。どう始めるべき？」「Vue 3.0で何が変わるのか？」「デメテルの法則を満たさないコードがだめな理由」「サーバサイドフレームワークを知りたい」「ライブラリの型定義が残念なときの対処法を教えて」「Null Object PatternはTypeScript的にどうなのか？」

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

[YYTypeScript#4]: https://yyts.connpass.com/event/147952/
[YYTypeScript]: https://yyts.connpass.com/

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

__今回の配信動画__

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">YYTypeScript#4の収録がアップされました！<a href="https://t.co/EawzgbM4mW">https://t.co/EawzgbM4mW</a></p>&mdash; suin❄️TypeScriptが好き (@suin) <a href="https://twitter.com/suin/status/1182629802798272513?ref_src=twsrc%5Etfw">October 11, 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#3「VueをTSで書いて良かったこと、大変だったことを教えて！」「React Hooksの最適な粒度って？」「クライアントサイドDDD」「皆さん、decorator自作してますか？」「Node.jsゼロインストールのメリットって何？」 - Qiita](https://qiita.com/suin/items/a37145a22233ae197a0f)

## 雑談


### axiosとfetchの違いが知りたい (じゅり)

esa.ioのお引越しツールを開発していて気になった。

・・・

* superagentというのもありますね（火種）
* axios → HTTPクライアントライブラリ
* fetch → HTTPクライアントライブラリ (ブラウザのネイティブ)
* サーバサイドは？
    * Node.jsにはもともとないので、ライブラリが必要
* [Fetch API - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API)
* axiosだと、リクエスト送信時やレスポンス受信時全般のフックを設定できたりとかします
    * 「特定のURLへリクエストする時は、cookieからuser tokenを取り出してheaderにセットしてから送る」とか設定すると、利用側は意識しなくても勝手にやってくれる
* axiosだと、JSONの取り回しが便利な感がある。
* Vue使ってる人はaxios馴染みあるよね
    * Vue公式にもfetch APIに対応できますって書いてある
    * メリットとしては外部リソースを必要としないこと
* polyfill
    * ブラウザによっては未サポートの機能が有るので、どのブラウザでも動かせるようにするために入れる
        * ブラウザがサポートしてる → ネイティブの機能を使う
        * ブラウザがサポートしてない → polyfillが動く
        * PromiseなんかはIEがサポートしてないので、IEで動かすならpolyfill必要だった記憶
* [nuxt.js は axios を捨てて ky になる様子 - Qiita](https://qiita.com/il-m-yamagishi/items/a823c1afbdf253e84a34)
    * 

### JSを学んでいるTS(JS)初心者がコマンドで実行するアプリケーションを作ってみようとした場合、どう始めるのが良いか (ぬーたけ)

* PHP歴23日
* [nouphet/get-connpass-member-list: コンパスの参加者リストを一撃で取得するスクリプト](https://github.com/nouphet/get-connpass-member-list) を作ったことがある
    * コマンド(cli)で実行するツール
    * このツールと同じ様なやつをつくってみるのはどうか

これをTSで書き直したい。

・・・

* PHPQueryを使っていたが、TSでは？
    * [cheerio - npm](https://www.npmjs.com/package/cheerio)
        * jQueryのインターフェイスとほぼ同じ。
        * `$`でDOM操作できる。
            * PHPでいうところのGoutte
* ここでなぜNode.jsが出てくるのか？
    * JavaScript(ECMAScript)の実行環境
    * 現状、サーバー上でのjs実行環境はNode.jsしかなかったと思う
* cheerioで取ってきて、パースすればできそう
* 開発にはts-nodeを使うと便利
    * 最初はts-node使わないのも楽しい
        * ちゃんとJSに書き換わっているのが分かるので
        * ts-nodeを使わないってどうやるの？
            * `ts-node src/index.ts` = `tsc && node dist/index.js`
        * PlayGroundとかはリアルタイムにコンパイルされて結果が見えるので、勉強にはおすすめですよ〜
            * http://www.typescriptlang.org/play/


### サーバサイドで重いバッチ書くとき気を付けてることとかあれば知りたいです！ (matmau5)

巨大なテキストファイルを読み込んでDBに突っ込むとか

・・・

* メモリがボトルネックになることがあるから
    * ストリーム処理する
        * 例1行ずつ読む
    * [Node.js中級者を目指す - このすみ堂 - BOOTH](https://konosumi.booth.pm/items/1545887)
        * 第7章がストリーム処理について
* DBに突っ込むならtransaction begin しておいてコケてもやり直しがしやすいようにした方が良さそう

### Vue 3.0で何が変わるのか？ (すいん)

* TypeScriptで書き直してると聞いたが。

・・・

* Reactのhookみたいなのが追加されるっぽい
* 結構がっつり書き方変わるイメージあります
* [Evan You氏がVue.js 3.0をプレビュー](https://www.infoq.com/jp/news/2019/03/vue-3-preview/)
    * 新しいコアは、圧縮時のサイズが20KBから10KBに削減される見込み
    * Vueは，バージョン3をTSXサポートを備えたTypeScriptで書き直すことで，開発者エクスペリエンスのさらなる向上を目指している。
* tsx
    * TS XML
    * JSXのTypeScript版
    * JSの中にXMLが書けるJSのサブセット
        * XMLリテラルというXMLがそのまま書けるのが特徴の言語
* TSXは型の恩恵を受けやすい
* もともとVueのエンジニアってJSXが嫌でVueを選んだ人もいるはずなので、どうなんだろう？
    * TSX書くならReactでいいじゃんみたいなことは言われそうな気はちょっとしますね・・・
* Vue2のテンプレートも今までどおり使えるのかな？
* デザイナーってJSX扱えるの？
    * vueテンプレートの場合は多少勉強してもらう必要があるが、そこまで難しくはないかも。
    * Reactの場合は、デザイナーさんにもTSX(のロジック以外)とCSS(styled-components)も書いてもらっています
        * コンポーネント分け方論争になったりします
        * CSSの中の条件分岐ロジックとか、変数とかも適宜やってもらってたりしています

### デメテルの法則 (かきうち)

これがだめな理由を知りたい。

```php
getAnimal()->getCat()->getAmericanShortHair()
```

* 元ネタ: [jurifulさんはTwitterを使っています: 「getAnimal()-&gt;getCat()-&gt;getAmericanShortHair()はあんまよくないってことだよね？どうすればよいの？🤔 #phper_oop」 / Twitter](https://twitter.com/juriful/status/1182255498277441536?s=20)


・・・

* この例はあんまり良くなかったと思う (じゅり)
* 実務でEC周りでgetを連鎖するコードを書いていて疑問だった。
* デメテルに反するとどういう問題があるのですか？
    * テストが大変になる
    * getの連鎖を解決できる、巨大なオブジェクトを用意しないといけなくなるので・・・

```javascript
describe('Hoge', () => {
    // Hoge#getXxx內部で return this.aaa.bbb.ccc.ddd.value とかやってると・・・
    const hoge = new Hoge({
        aaa: {
            bbb: {
                ccc: {
                    ddd: {
                        value: 1
                    }
                }
            }
        }
    })
    
    it('should return xxx', () => {
        expect(hoge.getXxx).toBe(1)
    })
})
```

* Viewにコードが散らばるよりは、モデルにgetterがあった方がテストの面でも、仕様追加変更の面でも便利に感じました
* そのクラスを見れば、何ができるのかがわかるようにするのが良さそう

```javascript=
// リファクタリング後
class Item {
    getItemPriceBySku(sku) {
        ...
    }
}

item.getItemPriceBySku('sku-XXXXX')
```

* 呼び出し元が、隣の隣のオブジェクトを知らなくても良くなるようにする
* Item *-> "0..n" SKU みたいな関係だと、#findXxx とか #filterXxx みたいなメソッド生やすことあります
    * 詳しい抽出条件は利用側で任意に設定できるので、これなら肥大化せずにすむんじゃないかなーと
    * 頻繁に使われる抽出条件が有るなら、それ自体独立した関数として定義するとか、固定のメソッドとして生やしちゃっても良いんじゃないかなと

```javascript
class Item {
    findPriceBy(finder) {
        return this.skuList.find(finder)
    }
}

// 特定のSKUに紐づく価格がほしい
item.findPriceBy(sku => sku.id === targetSku.id)


// 特定の日に発売された商品の価格がほしい
item.findPriceBy(sku => sku.publishedAt === 'xxxx-xx-xxTxx:xx:xx')
```

* 確かに、人が書いたコードで隣の隣の隣のオブジェクトとかを参照していると、テストがわかりずらかった経験があります


### サーバーサイドTypeScriptやったことないので、どういうフレームワークとかライブラリがあるのか知りたいです！ (KuuK)

何をやりたいかによる
ウェブアプリケーションを作りたい？

・・・

* TS純正 → Nest.js (フルスタックフレームワーク)
* express.js (マイクロフレームワーク)
* koa.js (マイクロフレームワーク)
    * rubyのsinatraみたいなイメージ
    * 薄くて良かった
    * expressを良くしたいというモチベーションで作った
    * 数百行でできている
    * ミドルウェアというプラグインを追加して使う
* 型定義がちゃんとしたものでないとTSの恩恵を受けづらいので、選ぶときはそこを注意したほうが良い
* DBだとTypeORM
    * Nest.jsだとバンドルされてる
    * Sequelize というのもある
* テンプレートエンジンは何がある？
    * ejx?
    * pug?
    * tsx を SSRする感じとか
        * クライアント側の見た目とサーバー側の見た目で合わせた内容でpdfを吐きたかった時にwkhtmltopdf使ってやりました
    * Gatsby
    * [node.js で使えるテンプレートエンジン - Qiita](https://qiita.com/satosystems/items/cf7b748c0f95c95aa48b)


### ライブラリの型定義が残念なときのワークアラウンドを知りたい (すいん)

作者に直してもらうのではなくて、自分で使うときに工夫するためのワークアラウンドが知りたい

・・・

* hoge.d.ts みたいの作ってinterface上書きしてる
* tsignoreを書いて回避
* tsconfigにtypeRootでも何でもいいので型定義を上書きをする
    * anyとかobjectを使っちゃってるようなところを、より厳密にする感じです？
        * methodが足りなかったりするのを生やしたり
        * 型定義だけ上書きしても実装は変わらないと思うのですが、型定義不備を補うって感じでしょうか
            * ですね
                * なるほど！
* PR送り先が無かったりするやつがあったり。。。

### Null Object PatternはTypeScript的にどうなのか？ (すいん)

https://dev.to/jamesmh/unhealthy-code-null-checks-everywhere-2720 を読んで感じた疑問。

・・・

- nullガードを書く
- union型でもいいんじゃない？という感想もある

```typescript
function doSomething(): null | Foo {}
```

- TS3.7からのオプショナルチェイニングで代替できる？
    - ?だらけになるのではー？
    - かなしい・・・
- 「nullかどうか」を考慮から追い出せるのがNullObjectPatternの旨味だと思ってます
    - オプショナルだとまさに?だらけになりそう、nullガードは分岐だらけになる
        - 結局「nullかどうか」を考慮することは変わらず要求されてる感
        - 安全にはなるけれど、考えるべきことは減ってない
    - 「存在しない」という状態が有るなら、それをNullObjectという形で一つの状態として明示的に定義した方が良さそうな気がします
- ちゃんと型が定義されていれば、Null Objectパターンじゃなくて良さそう
- コンパイル時に頑張るのが型で、実行時に落とさなようにするのがNull Object Patternって解釈であっていますかね
    - あってそう

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

* 初耳なワードを色々しれてよかった
* 「デメテルの法則」という言葉を知れた。
* 初心者向けの質問から中、上級者向けの質問まで幅広く楽しめました。
* サーバーサイドTypeScriptの話や、デメテルの法則の話が聞けて非常に勉強になりました

## YYTypeScriptは毎週やってます

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

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