2022-01-01から1年間の記事一覧

オブジェクト型の重箱の隅

TypeScript のオブジェクト型について比較的触れられる機会が少ないこと (重箱の隅) をただ集めただけの記事です. オブジェクト型やその周辺に明るくなりたい人, または任意の重箱の隅が好きな人向け. 挙動の確認は 2022-11-06 時点の最新版である 4.8.4 で…

TypeScript エラー処理パターン

M 年前にも N 年後にも人類は同じ話をしている. まとめ エラーの発生方法は throw と return に大別できる throw には簡潔さ, return には明瞭さと型安全性といった特徴がある どちらの方法がより適しているかはプログラムの規模, エラーの種類, ハンドリン…

TypeScript 4.8 でやることといえば: negate にていねいに型をつける

TypeScript 4.8 がリリースされました. これでやることといえば? そう, 数値リテラル型の符号を入れ替えることですね. type Negate<N extends number> = N extends 0 ? 0 : `${N}` extends `-${infer X extends number}` ? X : `-${N}` extends `${infer X extends number}` ? </n>…

TypeScript で実行時の入力を含む文字列を型で弾く

TypeScript (4.7 時点) において, 文字列に付けられる型には以下の 3 つ (とそのユニオン型) があります. 文字列型 string 文字列リテラル型 ("foo" など) テンプレートリテラル型 (`data-${string}` など) これらのうち, 実行時の入力, 特に事前にパターン…

共通化すれば良いとは限らない

ここのところ偶然なのか「共通化」という言葉を多く聞いているのですが, その言葉を聞くたびに身構えていることに気がついたので, この気持ちの出どころを共有しておきます. なぜ身構えているかというと, 共通化が必ずしもコードを良い状態にするとは限らな…

Optional Variance Annotations の挙動メモ

TypeScript 4.7 の optional variance annotations の挙動を若干勘違いしていたのでメモ. 例 1 (Playground): type Extends<A, B> = A extends B ? true : false; type Bivariant<T> = {}; type Bivariant_A0 = Extends<Bivariant<"foo">, Bivariant<"foo" | "bar">>; // true type Biv</bivariant<"foo"></t></a,>…

プログラムの複雑さ・表面積・グラフの構造

特に何かしらの出典はありません. プログラムの複雑さに対する大局的で直感的な指標として, 表面積とグラフの構造というのを個人的に意識しているという話. いわゆる code smell をどう嗅ぎつけているか. 表面積 プログラムは最も単純には 1 つの入力チャン…

TypeScript をもっと安全にする ESLint プラグイン

TypeScript の型安全性を高めるための, やや思想強めのルールを提供する ESLint プラグインを作りました. ひとまずは以下の記事で紹介したもののうち, それなりに重要度が高く, かつ機械的に検査しやすい「オブジェクトの具体的な形にアクセスするのを避ける…

コードや Pull Request をコミュニケーションの手段として使ってほしい

レビューなり, 過去の経緯を調べる目的なりでコードや Pull Request (以下 PR) を読むとき, 書かれていてほしいと思う内容が書かれていないことが少なくない. 例えば, 背景や目的 全体的な実装方針 (特に複数の PR で一つの目的が達成される場合) これまでや…

TypeScript 型レベルプログラミング フリースタイルガイド

TypeScript の型レベルプログラミングのための真面目なスタイルガイドではありません. 型なしラムダ計算で喜ぶような人間が使うための諸刃の剣です. この記事の内容は TypeScript の 2022 年 1 月時点での最新版である 4.5.4 に基づいています. 将来のバージ…

状態は単一の経路を使って参照しよう

React アプリケーションにおいて single source of truth と言った場合, 複数のコンポーネントで同じ値が必要なときは, それぞれのコンポーネントで独立に状態を管理して互いに同期をとるのではなく, ただ一つの場所で状態を管理し, 全てのコンポーネントは…