プログラミング

TypeScript をより安全に使うために その 1: オブジェクトの mutable な操作を避ける

ふだん TypeScript のコードレビュー時に参考に貼ったりしている内部ドキュメントがあるのですが, 内部では何かと人目につきにくいので, 内容を整えて公開していきます. TypeScript の型システムは安全ではありません. つまり型検査を通過したコードであって…

GitHub Actions で mkr を使う

mkr とは何ですか? Mackerel の CLI です. GitHub Actions 上で mkr をセットアップする setup-mkr アクションを作りました. github.com こういう感じで uses: susisu/setup-mkr@v1 と一行書くだけで mkr コマンドが使えるようになります. steps: - uses: su…

exactOptionalPropertyTypes によせて

TypeScript 4.4 に exactOptionalPropertyTypes というオプショナルなプロパティに関するコンパイラオプションが追加されるのを受けて, そもそもオプショナルなプロパティとは何なのか, どういったときに使うと良いのか, exactOptionalPropertyTypes がどう…

引数の型を推論してから受け付けるかどうかを決める後出しパターン

2023-05-24 追記 改訂 + α 版を書きました. お題 具体例として, ちょうど長さ 3 の文字列のみを引数として受け付ける関数を作ります. こんな関数を作って何がしたいのかは不明. 先出しパターン よくある手段としては「ちょうど長さ 3 の文字列」のような制約…

セルフコードレビュー

自分の書いたコードのレビューを依頼するとき, 必ず先にセルフレビューするようにしていて, まあまあ上手くいっていると思っている. 元々のモチベーションとしてはコードの品質の向上と (本物の) レビュワーとのコミュニケーションのつもりだったけど, 本来…

アプリケーションのコード規模に対する雑感

主観です 規模はコード行数 (LOC) で考えています 体感的にわかりやすいため 言語・フレームワーク・対象とするドメインなどによって何倍もずれるはず あくまでアプリケーションについての話です ライブラリについてはまた事情が変わってくる コードについて…

非対称な状態間の同期の実装メモ

状態間の同期は一般的な話題ではあるのですが, 例として React の制御コンポーネントの実装を題材にします. ここで非対称な状態とは, 各状態のとり得る値の集合の間に一対一の対応がないことを指しています. というか一対一に対応するのであればふつうは状態…

コード中の定数の greppability と TypeScript の進化

TL; DR コードの greppability のために文字列操作を禁止する目的で string literal type (の union) なら受け付けるが string は受け付けないという関数を作っていたのだけれど, どうにも TypeScript が賢くなりすぎてしまった— 塩水うに (@susisu2413) Jan…

ここ 1 年くらいで作った有象無象まとめ

私が個人的に作ったものはいくつかはこのブログで紹介したりしていますが, そのように個別に紹介するほどでもない有象無象たちにも出番を与えてみようという企画です. だいたい 2019 年末ぐらいからのものが入っています. tyde github.com 型安全で自分好み…

TypeScript の型の再帰上限を突破する裏技

TypeScript 4.1 で再帰的な conditional type の定義に制限がなくなり (ref), 今後ますます再帰的な型定義をする / 触れることが多くなろうかと思います. 一方で TypeScript が型をインスタンス化する際の再帰の上限はそこそこ厳しく, ちょっと複雑なことを…

Template String Types でパス文字列を解析してクエリする

※この記事に含まれる内容は TypeScript 4.1 のプレビュー版のものです. 今後仕様が変わり動かなくなる可能性もありますのでご注意ください. 話題の template string types で早速遊んでみます. ゴール .foo[1].bar といった形のパス文字列を型レベルで解析し…

TypeScript で次元つきの物理量を安全に扱う

キーワード: 型レベル整数, 幽霊型 前回の記事の予告通り, TypeScript 4.0 で次元つきの物理量の計算を安全に行うためのライブラリを作ってみました. ただし現状では PoC で, 実用に足るかまでは考慮していません. github.com 物理量についての計算を行う場…

Variadic Tuple Types を使った型レベル自然数演算

つい先日 TypeScript 4.0 RC がリリースされました. めでたいですね. さて TS 4.0 の目玉機能といえばなんといっても variadic tuple types ですが, これが型レベルで自然数の計算をしたいナウなヤングにバカウケということで, 界隈では一時期のタピオカミル…

テストの説明に安易に「正しく」とか書かない

みなさんテストは書いていますよね. 書いていなければふりだしに戻る. 例えば関数 add に対して, 以下のようなテストコードがあるとします. describe("add", () => { it("正しく計算できる", () => { expect(add(1, 2)).toBe(3); }); }); よさそうですね? も…

TypeScript で Algebraic Effects

型をそえて. TL; DR (実用には向かないものの) TypeScript で Algebraic Effects (たぶん) を扱うライブラリを作ってみました. github.com 背景と課題 コールバック地獄の解決 たとえば Haskell や Scala にあるような Either モナドを, TypeScript でも使い…

TypeScript で GADT っぽいの

TypeScript で Haskell にあるような GADT (Generalized Algebraic Data Type) っぽいものをどう表現できるかという話. GADT を使いたくなる例 式をデータとして表現したいことありますよね. あると言ってくれ. 例えば数値と数値上の関数, そして関数適用が…

TypeScript で型レベル Brainfuck

2024-04-15 追記: 内容をアップデートした記事を書きました. susisu.hatenablog.com TypeScript の型システムはチューリング完全ということが知られていますが, 同じくチューリング完全な言語である Brainfuck のインタプリタを実装することで, その計算能力…

TypeScript で型レベル階乗

こんなことがやりたかったんじゃないし, 誰もそんなこと望んじゃいない. でもやる. 動作確認している TypeScript のバージョンは 3.8.3 です. ゴール TypeScript で階乗を計算します. 型レベルで. type F = Factorial<3>; // F = 6 アイデア まずタプル型の …

TypeScript で型レベル Permutations

遊びです. 真に受けないでください. 動作確認している TypeScript のバージョンは 3.8.3 です. ゴール タプル型 XS から, 要素の置換 (permutations) の union 型を作る Permutations<XS> を作ります. type P = Permutations<["A", "B", "C"]>; // P = ["A", "B"</xs>…

TypeScript でネストされたオブジェクト型の書き換え

↓ に対するアンサーソングです. blog.3qe.us 例えばこういう感じの型 T があって, ネストされた内側にある baz の型を number から string に書き換えたいとしますね. type T = { foo: { bar: { baz: number, }, }, }; もしこれが, 書き換える対象のパスを […

Tagged Templates でたのしい Router & Reverse Router

この記事は はてなエンジニア Advent Calendar 2019 15 日目の記事です. 昨日は id:polamjag さんによる Next.js で Google Analytics を使う・2019年冬 - polamjaggy でした. qiita.com こんにちは, Mackerel 開発チームでアプリケーションエンジニアをして…

辞書を作る関数に TypeScript で執拗に型をつける

未来人のみなさまご機嫌いかがでしょうか. この記事が書かれた時点の TypeScript のバージョンは 3.6.4 です. お題 以下の JavaScript の関数に TypeScript で型をつけることを考えます1. function makeDict(prop, entries) { const dict = {}; for (const e…

スクリーンショット撮影のために Puppeteer を操る

先日開催された Kyoto.js 16 で, Puppeteer を使ってスクリーンショットを撮影するためのフレームワーク / ツールを作ったことについて発表しました. いつもありがとうございます. kyotojs.connpass.com スライドはこちら. speakerdeck.com 成果物はこれ. sc…

パターンマッチの構文が前置か後置か覚えられない人がやりがちなこと

突然思い出して随分前のネタを引っ張り出してきました. OCaml と Scala のパターンマッチ構文は共に match というキーワードを使いますが, 前置 / 後置が異なるため, 交互に書いていると混乱して結構な頻度で間違えます. let y = match x with | Some n -> n…

subtype 多相, never, union を有効活用していこうな

まずは MonadPlus ばんじゃーいとこういう感じに mzero と mplus を定義してみる. mzero が関数になっているのは TypeScript ではこうしないと (関数以外の値を) パラメータ多相にできないため. ちなみに Parser<A> の A は結果の値の型で, Parser はこれについ</a>…

パーサコンビネータライブラリを更新した (2 年ぶり 2 回目)

2 年に一回更新することでおなじみの (?) JS 製パーサコンビネータライブラリ loquat の v3 をリリースしました. github.com 変更点の詳細はここには書かないのでリポジトリを見てください. どうせ誰も使っていないでしょうし... 以下は雑な話題です. TypeSc…

Node.js のパッケージ情報をいい感じに表示するやつを作った

ppp という, Node.js のパッケージ情報を表示するコマンドラインツールを作ったのでそのご紹介です. github.com それ npm view で良いじゃん, とか, 前も似たようなの作っていなかった? などと思った方もおられると思いますが, 新しく作ったのにはちゃんと理…

コマンドの出力を HTML に変換して貼り付ける

みなさんも生きていればコマンドの出力をブログに貼り付けたいということがあるでしょう. というわけでコマンド出力をなんとか HTML にして貼り付ける方法のご紹介です. TL; DR: script -q /dev/null <command> | ansi2html -i | pbcopy まず HTML は基本的には以下の</command>…

【下書き】 ドラッグ&ドロップ UI をテストしたい時

気が向いたらそのうちサンプルコードとか付けてちゃんと書きます. 向かなければそのままです. ドラッグ&ドロップには色々な要素が絡んでくる バグが入り込みやすい どうテストしたら良いか? / どうバグを再現したら良いか? 「なんかある操作をしたらバグった…

「分割」できる疑似乱数生成器

この記事ははてなエンジニア Advent Calendar 2018 の 6 日目の記事です. こんにちは, id:susisu です. Mackerel のアプリケーションエンジニアをしています. 最近は新しいカスタムダッシュボード機能を開発したりしていました. mackerel.io この記事ではタ…