これは2019年10月25日に開催したTypeScriptイベントYYTypeScript#6のイベントレポートです。
YYTypeScriptは一言で「TypeScripterの部室」です。発表者の話を聞く「一方向的な勉強会」とは真逆で、TypeScriptについて、雑に・ゆるく・ワイワイ話しながらTypeScripter同士の交流を深める「双方向的な座談会」の形式になります。集まった人たちで「今日話たいこと」「聞きたいこと」をいくつか挙げていき、それをテーマに雑談していきます。
今回の配信動画
#YYTypeScript 6の収録がアップされました!https://t.co/w9QMbmNWFS
— suin❄️AWS & TypeScript (@suin) October 25, 2019
過去回の配信動画 → YouTubeプレイリスト「YYTypeScript」
前回 → YYTypeScript#5「TSの好きな機能って何?」「enumは避けるべきか」「TSを選んだ理由を教えて」「業務で犯した型がらみの失敗談」「ソースマップも含めてnpm publishすべき?」「関数で書く派ですか?クラスで書く派ですか?」 - Qiita
雑談
JavaScriptのプロジェクトにTypeScriptを入れるときの知見を聞きたい (えあんぬ)
-
allowJSの知見など知りたい。
-
1,900ファイルぐらいあるけっこうでかいプロジェクト
- 1900ファイルあるプロジェクトでJSで書くのもしんどそう。。
-
ts化して型安全にしたい
-
ts化したらエラーが多すぎてつらい
-
noImplicitAny: false
をセットする -
allowJS: true
? -
// @ts-ignore
とコードに書くと、次の行のコンパイラチェックを抑制できる- ファイル単位での記述になるので、どうしてもやむを得ない時に、ピンポイントで使える
-
そんなにファイル数がないプロジェクトで
- tsconfigで設定をかなりゆるめにして、1ファイルずつTSに移行した
-
noImplicitAnyはできればやりたくない
- 既存コード用のtsconfigと、新規コード用のtsconfigをわけるとか?
- パッケージルートの
tsconfig.json
をroot: true
にして、ディレクトリ内部でextendsできます、たしか
- パッケージルートの
- 既存コード用のtsconfigと、新規コード用のtsconfigをわけるとか?
-
tslintで型アノテーションを強制する
- CIで型アノテーションがなければ落とす
-
commitlintで、lintで失敗したらコミットさせない、という手もあるかも
- commitlintいいですよね
aspida.jsについて聞く (ふぃろまぎ)
- aspida.js (アスピーダ JS)
- 型定義を記述しておけば、静的に型付けされたAPIクライアントの実行コードを自動生成してくれるツールです。
- 型定義ファイルだけでなく、実際に動作するtypescriptコードが生成されます。
- スキーマファイルってどんな?
- TypeScriptで
interface
を書いていく。
- TypeScriptで
- 興味ある人で開発に参加してくれる方募集中だそうです。
- ASTとかの知見が有る方は、特に歓迎したいそうです
- スキーマ定義があれば、サーバサイドも自動生成できそう。
- APIクライアントを自分で作ろうとすると、ラッパーを書く必要があるが、aspida.jsはそれをやってくれる
- TypeScriptの
interface
でIDLが書けたらいいなと思っていた。- aspidaとか、↓こういうのを待ってた
- AWSが公開したインターフェイス定義言語(IDL)Smithyのドキュメントを通し読みしてみた | DevelopersIO
Webstormとprettierの相性悪い? (やました リモート)
Webstormを使っているんですが、formatをsave時に使いたくsuinさんの記事をQiitaで見つけ設定しました。でも、prettierが激遅ぷんぷん丸で困ってます
...
- たしかにWebStormは保存してから整形されるまでワンテンポあるかんじで、VS Codeを使っていた。
- 保存するとprettierが走ると思うのですが、その間にコードに手を加えると、編集が消えたりするんです
- VS Codeでは発生しないんですか?
- commitするときに整形しては?
- 解決しないのでsuinの宿題とします。
TypeScript 3.7では何が変わっているのか、どんな機能が増えているのか (れおりん)
- Optional Chaining
?.
- Rubyで似たようなやつがある
- むかしは
foo && foo.bar && foo.bar.buz
ってやってた - tc39/proposal-optional-chaining
-
_.get(foo, 'bar.buz')
も有ったけど、型が死ぬ-
https://www.npmjs.com/package/ts-get-safe
- どんな型定義になってるか気になる
- 型定義はっときますね↓
- どんな型定義になってるか気になる
-
https://www.npmjs.com/package/ts-get-safe
function getSafe<TObject, P0 extends keyof TObject, A1 extends GSArrEl<P0, TObject>, P2 extends keyof A1, P3 extends keyof A1[P2], A4 extends GSArrEl<P3, A1[P2]>>(obj: TObject, p0: P0, a1: number, p2: P2, p3: P3, a4: number): A4;
- Nullish Coalescing
??
-
||
と何がちがう?-
||
は0
とか''
でも、右辺が評価される -
null
とundefined
のときだけ。
-
-
- Assertion Functions
-
type predicate
の強い版?
-
function assertString(value: unknown): asserts value is string {
if (typeof value !== 'string') {
throw new Error('...')
}
}
assertString(value) //=> exceptionが発生しうる
value.toUpperCase() // コンパイルが通る (valueがstringだとわかっているので)
- コンパイルしてもチェック処理は残る。
- チェック内容がバグってると、コンパイラに間違った情報が伝わるところは注意
-
Better Support for never-Returning Functions
-
Recursive Type Aliases
-
新機能はどうやって決まるの?
- ECMAScript由来はTC39
- TypeScript固有のやつはGitHub issueでディスカッション?
- assertion function は↓のPR起点?
- Design Meetingというのやってる?
- どうやって決めているのか分からないので宿題。
- 3.7正式版のリリース予定は11月5日
- 4時間前にRCが出てるので、概ねスケジュール通り
- TypeScript 3.7 Iteration Plan · Issue #33352 · microsoft/TypeScript
- 今後入る予定のESのprivateが気になる
- Private named instance fields by mheiber · Pull Request #30829 · microsoft/TypeScript
- どっちで書くかでチーム内で宗教論争が起きそう
- ECMAにしたがったほうがよさげ
関数型で書いているときのテストの仕方について (えあんぬ)
- 手続き型と関数型はどうちがうの?
- 手続き型は、どうやって処理するかを書いていく
- 関数型は、より宣言的で、関数と関数を組み合わせて作っていくかんじ
- 関数合成という考え方がある
- 関数型プログラミングは、関数が第一級市民
- 元々JavaScriptの作者が、関数型言語作りたかった人らしいから、JSは最初から関数型っぽい言語設計になってるっぽいですね
- 参照透過性
- 引数が同じだったら、何度やっても同じ結果が得られる
- functionだけexportすることがあるが、functionが依存するfunctionをモックにするのかどうか
-
require
に噛んで依存先をモックにするライブラリがあるけど、- ちょっとツール依存な気がする
- 外部にexportする目的には、interface or type を TS で書いて、実装はそれぞれexportしてテストはそれをimportしてテストでいいと思う
- ports and adapters デザインパターン(ヘキサゴナルアーキテクチャ)とか、インターフェース分離とか、DIP(依存性逆流)とか使うと、外に見せるものを限定しつつ、関数を全部テストするみたいなこともしやすいですね
- 引数に関数を持つものをテストするときは、jest.fn() でモック作って雑にテストすれば大体いいような気がする
-
- 関数が依存する関数で、取り替えたい部分はカリー化するとか、引数で渡すとかするといいかも。
- DBを参照したり副作用をもっている関数は、引数で渡すといいと思う
- 副作用がなければくっついたままテストしてもいいと思う
- 関数とクラスの使い分けに悩んでる
- 依存物をもたせるならクラスでもいいのでは
- カリー化って?
- オブジェクト指向のビルダーパータンみたいに、段階的に関数を組み立てていける
const add = (v1: int) => (v2: int) => (v3: int) => v1 + v2 + v3
add(1)(2)(3) // => 6
const threePlus = add(1)(2)
threePlus(4) // => 7
threePlus(10) // => 13
カリー化とは違うけど、こういうファクトリーというか、段階的に組み立てる書き方は便利な気がしてる:
export interface HogePort {
read(name: string) => Promise<string>
}
export const createHoge = (context: string): HogePort => {
const read: HogePort['read'] = async (name) => {
// ... なんかすごいしょり
return `${name} ${context}`
}
return { read }
}
// カリー化とは違うけど、こういうファクトリーというか、段階的に組み立てる書き方は便利な気がしてる
const createCommandRunner = (conf: Config) => (command: Command) => command.run(conf)
// テスト時のコード
const command = new HogeCommand()
const test = createCommandRunner(testConf)
test.run(command)
// 本番環境のコード
const prod = createCommandRunner(prodConf)
prod.run(command)
クラスの設計について (かきうち)
メールを送るクラス
使う側からBodyを渡す
結果を受け取りたい
・・・
メールとメールを送るクラスを分けるといいかも。
const email = { subject: '...', body: '...' }
emailSender.send(email)
中途半端なメールを作るなら、それこそBuilderパターンとか、カリー化がいいかも。
const createMail = (subject: string) =>
(sender: string) =>
(body: string) =>
(receiver: string) => new Mail(subject, receiver, sender, body)
const sendTo = createMail('hoge')('example@gmail.com')('fuga')
const mailList = users.map(user => sendTo(user.mail))
interface Mail {
subject: string
sender: string
// ...
}
export function createMailSender(mail: Partial<Mail>) {
// 全部そろってたら、完成版MailSenderを返す
// そろってなかったら、Builderを返す
// とか……
// - conditional typeとか使えたら夢が広がりそう
}
- PHPですが、参考までに: PHP: Builderパターンの実装手順 #1【基礎実装】
TypeScriptのエディタはVS CodeかIntelliJか (れおりん)
何がいいのか、どういう違いがあるのか?
- VS Code使ってる勢: 3
- WebStorm勢: 2
- IntelliJ勢: 3
・・・
- WebStormだとprettier重い
- VSCode は無料で誰でも使えるから、環境統一に便利だと思ってたり
- IntelliJ全員買えるくらいだといいんですけど、なかなかそうはいかなですもんね
- あと、個人的な偏見かもしれないけど、設定を全くしてない状態では、IntelliJ よりも、VSCode が使いやすい気がする
- VS Codeは起動が速いので、TSしか触らないときはVS Code
- VS Codeは Live Shareのプラグインが良く出来てて、ペアプロするならこれになっちゃいました
- JavaとかScalaとかやってるチームや人は、慣れてるIntelliJ でいいような気もする
参加してよかったこと(参加者の感想)
- クラスや関数をどう作るかについての議論が楽しかった + 自分の感覚を言語化することができて良かったです
- aspida.js の存在を知れたこと
- カリー化の説明聞けたこと
- カリー化を知らなかった。便利良さそうだから使ってみよう!!
- プログラム好きな人が集まってる雰囲気を感じられたこと
- 1900ファイルあるJavaScriptのプロジェクトにTypeScriptを入れる話は生々しくて面白かった
YYTypeScriptは毎週やってます
YYTypeScriptについてワイワイ話したい方は、YYTypeScriptのイベント情報をチェックしてみて下さい。
以上、YYTypeScriptのレポートでした。次回もワイワイやっていきたいと思います! では、また来週!