ESLint の共有設定を Flat Config に対応させる

まえがき こんにちは, 人間 ESLint です. そんな人間 ESLint の私ですが, 私一人があらゆるコードに注意深く目を通して, さらに修正案まで提示するというのは大変です. 多くの問題は機械的に検知できるはずなので, そういった仕事を私の代わりにしてくれるメ…

Null Object is a ...

What? Null Object パターンとは プログラムを書いていると, 何もしない・何もないということを表したいシチュエーションがしばしば登場します. ナイーブな実装ではこのような場合に null のような特殊な値を使いますが, 多くの言語では null に対してはメソ…

カーソルの上下移動の思い出

突然ですが問題です. あなたは以下のテキストを編集していて, カーソルは一行目四列目 (_ の位置) にあります. Jan_uary February March 下矢印 ↓ キーを一回押したとき, カーソルはどの位置に移動するでしょうか? . . . はい, カーソルは一つ下の行の同じ列…

ブログのデザインを変えた

このブログでは長らく Airmail というデザインテーマを使っていたのですが, レスポンシブデザインに対応していないなど, 現代の使い方 (アクセスのされ方) に照らしてみるとやや時代遅れという感が否めませんでした. blog.hatena.ne.jp そんなわけで体験を現…

TypeScript で Cake Pattern

TypeScript で Cake Pattern っぽい DI (依存性注入) をするためのライブラリを作ったので, そのご紹介です. この記事での解説や他の手法との比較は前回の記事を前提とするので, まずはこちらをお読みください. Scala における Cake Pattern Cake Pattern は…

TypeScript の DI 手法あれこれ

TypeScript で DI (依存性注入) するためのライブラリを作ったんですが, それを紹介する前に既存手法をまとめておいた方が説明が楽だなと思ったのでまとめておきます. そもそも DI の目的とは, みたいなところは詳しく説明しないのであしからず. 手法の比較 …

中止ボタンがしいたけに見えて困る

令和最新版. Vivaldi でアイコンがカスタマイズできるようになっている テーマ設定画面を眺めていたら, Vivaldi 6.0 からツールバーのアイコンがカスタマイズできるようになっているのに気がつきました. 流石 Vivaldi です (?) vivaldi.com しいたけ復活 こ…

型に対する述語で引数に制約をかける

以前にも同様の記事を書きましたが, 今回はその改訂 + α です. 動作は TypeScript 5.0.4 で確認しています. Playground で試しながら読むとわかりやすいかもしれません. おさらい まずは TypeScript において, 関数に渡される引数に制約をかけたいときに通常…

TypeScript 型レベル関数型プログラミング in 2023

ちょっと前に話題になった hotscript の技法の紹介やら, ラムダ計算を TypeScript の型にコンパイルする話やらなんやら. 通常の型レベル関数 TypeScript の型エイリアスはパラメータを取れるので, これは型レベルの関数であるとみなせます. type IsNumber<X> = </x>…

Go 素振り日記

これは日記なので, 読むことでなんらか知見が深まることを期待したり議論を始めようなどと思わないこと. Splittable PRNG を Go に移植した たまには Go 力 (ぢから) が鈍らないように素振りをしておきます. 素振りが目的なので特に新規性とかはありません. …

コード書き仕草

たまには雑談っぽいことでも書くか〜 他の開発者のためにコードを書く コードを書くにあたっての話題は尽きることがないです. ざっと思いつくようなことを挙げてみるだけでも, 性質 可読性 柔軟性 堅牢性 変更容易性 原則 驚き最小 DRY SOLID 道具 コーディ…

CloudFront Functions で Next.js のパス解決の真似をする

Next.js から static export した HTML を S3 に配置して CloudFront から配信する, というのはそこそこよくある構成なんじゃないかと思います. 知らんけど. ところで素朴に CloudFront の origin に S3 を指定するだけでは, ページのパスの解決がうまくいき…

Node.js の perf_hooks で雑に関数のパフォーマンス計測

イントロ TypeScript で Array#filter を使うとき, 型が期待通りに絞り込まれないというトラブルがよくあります. const xs: (number | undefined)[] = [1, undefined, 2]; const ys: number[] = xs.filter((x) => x !== undefined); // ~~ // Type '(number …

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

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 と言った場合, 複数のコンポーネントで同じ値が必要なときは, それぞれのコンポーネントで独立に状態を管理して互いに同期をとるのではなく, ただ一つの場所で状態を管理し, 全てのコンポーネントは…

再帰的型定義ではオブジェクト型のプロパティの遅延評価に注意

この記事の内容は typescript@4.5.4 で動作確認しています. TL; DR TypeScript において, オブジェクト型のプロパティは必要になるまで評価が遅延される 遅延されていたプロパティの評価が行われるときには, TypeScript 4.5 の末尾再帰の最適化が効かない 例…

CloudWatch Logs Insights を使って Mackerel 上にアプリケーションのメトリック監視環境を手早く構築する

この記事は Mackerel Advent Calendar 2021 の 15 日目の記事です. 昨日は id:kazeburo さんの mkr plugin install 時の403 API rate limit exceededエラーを回避する方法 でした. こんにちは id:susisu です. 普段は Mackerel 開発チームでアプリケーション…

TypeScript をより安全に使うために まとめ

こういう一連の記事を書きました. susisu.hatenablog.com susisu.hatenablog.com susisu.hatenablog.com TypeScript の型安全性 TypeScript の型システムは健全ではありません. TypeScript Design Goals にある通り, そもそも言語設計の段階で完璧な型安全性…

TypeScript をより安全に使うために その 3: オブジェクトの index signature とオプショナルなプロパティを避ける

どんどんタイトルが長くなっている. 前回はこちらです. susisu.hatenablog.com 引き続き環境は以下を前提とします: TypeScript 4.4 (この記事を書いている 2021 年 11 月時点の最新版) strict: true # おさらい # Index signature オブジェクト型に index si…

TypeScript をより安全に使うために その 2: オブジェクトの具体的な形にアクセスするのを避ける

前回はこちら. susisu.hatenablog.com 引き続き環境は以下を前提とします: TypeScript 4.4 (この記事を書いている 2021 年 11 月時点の最新版) strict: true # 原則: オブジェクトの具体的な形にアクセスするのを避ける ここで「オブジェクトの具体的な形に…

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

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