TypeScriptの「型が通る」だけでは足りない。anti-slopで根拠の薄いコードをCIから止める
本文の状態
日本語全文を表示中
詳細モードで約24分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Algomatic Tech Blog
Algomatic のエンジニアは、TypeScript の型検査が実行時の安全性を保証しない点を指摘し、根拠の薄いコードパターンを CI で検出する「anti-slop」ツールの導入と活用方法を提案している。
AI深層分析を開く2026年9月4日 13:12
AI深層分析
キーポイント
型検査と実行時検証の乖離
TypeScript の型チェックが通っても、入力値の中身を検証していないコード(例:`as object as User`)は存在し、実行時のリスクが残る。
AI コーディング時代のレビュー課題
AI エージェントによる実装速度の向上に伴い、「型エラーにはならないが根拠もないコード」を人が見つける負担が増大するため、ツールへの任せる必要性が高まる。
anti-slop ツールの機能と限界
Oxlint 向けルール集である anti-slop は、型の根拠を失わせやすいパターンを構文レベルで拒否するが、実行時の値検証や完全な型解析を行うものではない。
導入における設計判断の重要性
便利だからといって全ルールを導入せず、どの設計判断を自動化したいかを理解した上で、`unknown` やモックへの制限など方針に沿って選定する必要がある。
型アサーションは実行時の検証ではない
型アサーションはコンパイラへの宣言に過ぎず、荷物の中身を確認する検品プロセスとは異なる。根拠のないアサーションを増やすと、型検査をすり抜けるリスクが高まる。
重要な引用
TypeScript の型検査が通ることは大切です。ただし、それだけで実行時の安全まで保証されるわけではありません。
「型エラーにはならないが、型を信じる根拠もないコード」はレビューで見つける必要があります。
anti-slop は、構文とスコープ情報から、型の根拠を失わせやすいパターンを 15 個のルールで拒否します。
「型アサーションは荷札の貼り替えに近い」
編集コメントを表示
編集コメント
本記事は、AI によるコード生成が一般化する現代において、型システムの限界を補完する具体的なプラクティスを提示している。開発チームは、ツールの導入前に自社の設計方針と照合し、安易な全ルール適用を避けるべきである。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。

こんにちは。AlgomaticでソフトウェアエンジニアをしているGo(@53able)です。
TypeScriptの型検査が通ることは大切です。ただし、それだけで実行時の安全まで保証されるわけではありません。
たとえば、次のコードはTypeScript上ではUser型として扱えます。
const user = input as object as User;しかし、このコードはinputの中身を検証していません。objectを経由して、コンパイラへ「これはUserとして扱ってよい」と伝えているだけです。
AIコーディングエージェントによって実装が速くなっても、このような「型エラーにはならないが、型を信じる根拠もないコード」はレビューで見つける必要があります。人が同じ指摘を繰り返すより、構文として判定できる部分はツールへ任せた方が、基準を揃えやすくなります。
そこで試したのが、Oxlint向けのルール集であるanti-slopです。
anti-slopは、構文とスコープ情報から、型の根拠を失わせやすいパターンを15個のルールで拒否します。実行時に値を検証した事実や、TypeScriptの型情報全体を追跡する型解析ではありません。
ただし、unknownやモジュールモックまで制限する、方針のはっきりしたツールです。便利そうだから全ルールを入れるのではなく、どの設計判断を自動化するのか理解してから使う必要があります。
先に整理する3つの前提
anti-slopの狙いを理解するには、TypeScriptの型、Lint、CIがそれぞれ何を点検するかを先に分けておきます。
プログラムへ入ってくる値は、「倉庫へ届く荷物」にたとえられます。型は荷札、実行時検証は開封検品、Lintは作業手順の点検、CIは出荷前の関所に相当します。
TypeScriptの型は荷札に近い
TypeScriptは、JavaScriptへ変換する前にコードの型を検査します。たとえば、数値を受け取る関数へ文字列を渡すと、実行前に誤りを見つけられます。
荷物にたとえると、TypeScriptは「この箱には書籍が入っている」「この棚には食品だけを置く」といった荷札と配置ルールを照合する仕組みです。荷札同士の矛盾は見つけられますが、外部から届いた箱を自動で開けて、中身まで確かめるわけではありません。
TypeScriptの型情報は、JavaScriptへ変換されると基本的に消えます。外部APIから受け取った値が本当にUserの構造を持つかどうかは、TypeScriptだけでは確認できません。実行時に中身を確かめるには、パーサー、スキーマ、型ガードなどが別に必要です。
型アサーションは荷札の貼り替えに近い
value as Userのas Userを「型アサーション」と呼びます。これは値をUserへ変換する処理ではありません。コンパイラに対して、開発者がその型を知っていると伝える構文です。
荷物にたとえると、箱を開けずに「内容不明」の荷札を「User」へ貼り替える操作に近いものです。中身は変わりません。検品済みだから貼り替えるのであれば筋が通りますが、検品していない箱へ新しい荷札を貼っても、安全になったわけではありません。
型アサーションには正当な使い道があります。ただし、根拠のない型アサーションを増やすと、型検査をすり抜けやすくなります。冒頭のinput as object as Userも、実行時の確認を増やすのではなく、コンパイラが見る荷札だけを二度貼り替えています。

Lintは手順書の点検、CIは出荷前の関所
Lintは、コードを実行せずに、あらかじめ決めた規則への違反を探す仕組みです。倉庫の比喩なら、「未検品の箱に確定ラベルを貼らない」「貼り替えた理由を記録する」といった作業手順の点検に当たります。
CIは、GitHubなどへコードを送ったときに、テストやLintを自動実行する仕組みです。anti-slopをOxlintへ登録すれば、ルール違反でCIジョブを失敗させられます。GitHubでPRのマージも止めるには、そのジョブをブランチ保護またはrulesetのrequired status checkに設定します。
整理すると、TypeScriptは荷札同士の整合性を調べ、anti-slopは荷札の扱い方を調べ、CIはその点検を変更のたびに実行します。

Oxlintとは
Oxlintは、JavaScriptとTypeScript向けのLintツールです。Oxcプロジェクトの公式ドキュメントによると、Rustで実装され、ESLintの主要ルールやTypeScript、React、Jest、Vitestなどのルールを組み込んでいます。
ESLintを使った経験があれば、Oxlintはコード規約違反を探す別のLintエンジンだと捉えるとよいでしょう。ただし、OxlintはTypeScriptコンパイラの代わりではありません。型の整合性を調べるtscと、コードの書き方や危険なパターンを調べるOxlintは役割が異なります。
倉庫の比喩では、Oxlintが検品担当者、個々のLintルールが検品項目に当たります。Oxlintだけでも多くの標準的な検品項目を持っています。anti-slopは、そこへ「二重に荷札を貼り替えない」「貼り替えの根拠を記録する」といった独自項目を追加します。
Oxlintは設定ファイルを読んでルールを実行する
Oxlintは、oxlint.config.tsなどの設定ファイルから、対象ファイル、プラグイン、有効にするルール、違反時の重大度を読み取ります。
最小限の設定は次のとおりです。
import { defineConfig } from "oxlint";
export default defineConfig({
rules: {
"no-debugger": "error",
},
});rulesには、ルール名と重大度を書きます。"error"にしたルールへ違反すると、Oxlintは診断を表示してエラー終了します。CIはその終了コードを見て、変更を通すか止めるか判断できます。
実行は次のコマンドです。
npx oxlint .末尾の.は、現在のディレクトリ以下を検査する指定です。実際のプロジェクトでは、package.jsonのlintスクリプトへ登録して使うことが多いでしょう。
{
"scripts": {
"lint": "oxlint ."
}
}
これで、ローカルでもCIでもnpm run lintという同じ入口を使えます。
anti-slopはJavaScriptプラグインとして読み込まれる
Oxlintには、組み込みルールに加えて、JavaScriptで書かれたルールを読み込むjsPlugins機能があります。anti-slopは、この仕組みを使うローカルプラグインです。
import { defineConfig } from "oxlint";
export default defineConfig({
jsPlugins: [
{
name: "anti-slop",
specifier: "./tools/oxlint/anti-slop/index.ts",
},
],
rules: {
"anti-slop/no-chained-type-assertions": "error",
},
});nameは、設定内で使うプラグイン名です。specifierは、コピーしたanti-slopの入口ファイルを指します。rulesでanti-slop/<ルール名>を有効にすると、Oxlintが通常のLintルールと一緒に実行します。この例はjsPluginsの概念を示す最小例です。実際に導入するときは、SkillまたはREADMEの手順に従い、既存のignore設定を残したままvendoredプラグインを除外します。
公式ドキュメントでは、JavaScriptプラグイン機能はalphaとされています。JavaScriptプラグインはESLint v9以降との互換性を目指していますが、カスタムパーサーと型情報を必要とするルールは未対応です。anti-slopは、この制約の中でASTとスコープ情報を使います。
anti-slopは@oxlint/pluginsの互換レイヤーを使って実装されています。既存のoxlintがある場合は、その解決済みバージョンと同じexact versionの@oxlint/pluginsを追加します。oxlintがない場合だけ、両方を同じcurrent exact versionで導入します。
anti-slopは、TypeScriptとJavaScriptを対象にしたOxlintプラグインです。プラグインとは、既存ツールへ機能を追加するための拡張コードを指します。
公式READMEでは、次のようなコードを拒否対象にしています。
- 二重の型アサーション
- 既知の値を広い型へ変えて情報を失う処理
unknownを引数、戻り値、辞書値として流す処理
Reflect.getやReflect.applyによる型情報の回避
- VitestやJestのモジュールモック
- 安全性の説明がない型アサーション
名前にある「slop」は、単に見た目が乱れたコードという意味ではありません。このプロジェクトが問題視しているのは、実装が正しいと判断するための証拠がコードに残っていない状態です。
たとえば、文字列をUserIdという専用の型として扱いたい場合を考えます。
const userId = value as UserId;この一行だけでは、valueをどのように検証したのか分かりません。anti-slopのrequire-safety-comment-for-type-assertionは、as const以外の型アサーションに、直前のSAFETY:コメントを求めます。
// SAFETY: parseUserIdで形式を検証した後にブランド型へ変換している
const userId = value as UserId;型アサーションを全面禁止するのではなく、レビューで確認すべき根拠をコメントとして残すルールです。コメントの正しさや実行時検証の有無は、Lintとは別にレビューとテストで確認します。
導入メリット1:同じレビュー指摘をCIへ移せる
anti-slopの利点は、レビューで繰り返していた指摘を再現可能なルールへ移せることです。
次の二重アサーションは、inputとUserの間にある型の不一致を、objectを経由して押し切っています。
const user = input as object as User;no-chained-type-assertionsを有効にすると、この書き方はOxlintのエラーになります。人が毎回「先に実行時検証が必要です」と指摘しなくても、同じ条件をローカルとCIで適用できます。
対象は型アサーションだけではありません。次の例では、startという既知のキーを持つオブジェクトへ、より広い型を明示しています。
const handlers: Record<string, Handler> = {
start: startHandler,
};Record<string, Handler>は、「文字列のキーとHandlerの値を持つ辞書」を表す型です。この型を明示すると、コンパイラが知っていたstartという具体的なキーの情報が失われます。
no-known-value-wideningはこの書き方を拒否し、型推論を維持するか、satisfiesを使うよう促します。
const handlers = {
start: startHandler,
} satisfies Record<string, Handler>;satisfiesは、値が指定した型を満たすか確認しながら、startのような具体的な情報を残すための演算子です。
荷札の比喩でいえば、Record<string, Handler>という大まかな荷札へ貼り替えるのではなく、この例ではstartという既知キーの情報を残したまま、保管基準を満たすか検査します。
検証では、広い型注釈を付けた例は拒否され、satisfiesへ置き換えた例はエラー0件で通りました。
Lintでレビューそのものが不要になるわけではありません。構文で判定できる問題を先に除き、設計意図や例外の妥当性など、人の判断が必要な箇所へレビューを集中させます。
導入メリット2:型の結論だけでなく、根拠を残せる
TypeScriptでは、最終的に正しい型が付いているように見えても、途中で型情報を失っていることがあります。
const loaded: User = loadUser();
const stored: unknown = loaded;
const user = stored as User;unknownは、「現時点では型が分からない値」を表します。このコードでは、いったんUserだと分かっていた値をunknownへ広げ、後から型アサーションでUserへ戻しています。
荷物にたとえると、検品済みのUserという記録をいったん「内容不明」に戻し、検品記録を確認せず、再びUserの荷札を貼っています。途中で捨てた情報を、根拠なしに復元している点が問題です。
anti-slopのno-widen-then-assertは、この流れを拒否します。
同じ考え方は、次のルールにも表れています。
no-known-value-widening: 既知の値を不要に広い型へ変えない
no-unknown-type-aliases:unknownを別名で隠さない
no-unsafe-dictionary-type:Recordなどの曖昧な辞書契約を作らない
require-safety-comment-for-type-assertion: 必要な型アサーションには確認済みの条件を残す
これらのルールに共通するのは、「型が付いた」という結論だけでなく、その型を信用できる理由を保つことです。
Lintの判定は、コードを書いた主体に依存しません。人が書いたコードにもAIが生成したコードにも、同じ受け入れ基準を適用できます。自然言語で書いた規約だけに頼る場合と比べて、違反箇所と終了コードが明確になります。
導入メリット3:未検証値を境界で検証する方針を促せる
unknownはanyより安全です。anyはほぼ自由に使えるのに対し、unknownは型を絞り込むまで、そのままではプロパティへアクセスできません。
ただし、unknownがアプリケーション内部を流れ続けると、どこで検証済みになったのか分かりにくくなります。
ここでいう「境界」とは、アプリケーションの外から値が入る場所です。APIレスポンス、設定ファイル、メッセージキュー、ブラウザストレージ、フォーム入力などが該当します。
倉庫なら、外から荷物を受け取る搬入口です。搬入口で開封検品を済ませれば、倉庫の内側では検品済みの荷物として扱えます。反対に、「内容不明」の荷物を奥の棚まで運ぶと、使う場所ごとに中身を確かめなければなりません。
anti-slopは、unknownの引数、戻り値、型エイリアス、辞書値を複数のルールで拒否します。また、場当たり的なtypeofによる絞り込みもno-runtime-typeofで制限します。
上流がルール説明で推奨するのは、外部から来た値を境界で一度検証し、アプリケーション内部では具体的な型を使う設計です。
// 外部入力を境界で検証する
const user = userSchema.parse(input);
// 内部には検証済みの具体型を渡す
saveUser(user);この例のuserSchema.parseは、値の構造を実行時に確認する処理を表しています。検証に成功した値だけをsaveUserへ渡せば、未検証の値を内部へ広げにくくなります。anti-slopはparseの実行やスキーマの完全性を検証するものではありません。
スキーマライブラリを使わず、型ガードで境界を処理する構成もあります。型ガードは、実行時の判定結果をTypeScriptの型絞り込みへ伝える関数です。
その場合、no-runtime-typeofには、型ガードやアサーション関数の中だけtypeofを許可するallowInTypeGuards設定があります。
import { defineConfig } from "oxlint";
export default defineConfig({
rules: {
"anti-slop/no-runtime-typeof": [
"error",
{ allowInTypeGuards: true },
],
},
});同じ型ガードを設定だけ変えて実行すると、既定設定ではtypeofが拒否され、allowInTypeGuards: trueではエラー0件になりました。READMEの設定例とも一致します。
この設定が必要かどうかは、既存プロジェクトがスキーマと型ガードのどちらを使っているかで変わります。ルールへコードを合わせる前に、入力検証の方針を確認するのがよいでしょう。
導入メリット4:導入手順までコーディングエージェントへ渡せる
anti-slopには、コーディングエージェントから導入するためのSkillが付属しています。
ここでいうSkillは、エージェントに作業手順と完了条件を渡すための文書とスクリプトの組み合わせです。
npx skills add dmmulroy/anti-slop --skill install-anti-slopSkillの手順には、次の作業が定義されています。
- 既存のパッケージマネージャーとOxlint設定を調べる
- プラグインを
tools/oxlint/anti-slop/へコピーする
- 現在の
oxlintと@oxlint/pluginsを導入する
- 既存設定を保持しながらプラグインと15ルールを追加する
- Lintと型チェックを実行する
- 変更差分と残った違反を報告する
指定コミットのインストーラは、plugin assetsを新規ディレクトリへ再帰コピーします。既存の宛先がある場合は、--forceなしでは上書きを拒否します。
ファイル数や拒否確認のために追加した独自マーカーは、インストーラ自身の出力ではありません。記事で確認できるのは、コピー先と設定ファイルを示す出力、および既存宛先を拒否するメッセージです。
Skillは設定断片を提示するだけではなく、調査、コピー、設定、検証、報告までの完了条件を定義しています。エージェントへ依頼するときに、どこまで終われば導入完了なのかを共有しやすくなります。
ただし、Skillはローカルファイルを変更し、依存パッケージを追加します。実行前にSkill本文と同梱スクリプトを読み、Gitで変更前の状態へ戻せることを確認しておくと安心です。実行後は、追加された依存関係、設定差分、Lint結果を人が確認します。
導入メリット5:ルールを自分たちで所有できる
anti-slopは、固定されたnpmパッケージとして利用するのではなく、ソースコードを対象リポジトリへコピーするvendoringを前提としています。
vendoringとは、外部ライブラリのソースコードを自分たちのリポジトリへ取り込み、そこで管理する方法です。
倉庫の比喩なら、外部業者の検品規則を毎回参照するのではなく、規則集の写しを自社へ置き、自社の責任で改訂する方法に近いものです。どの版を使うか自分たちで決められる一方、改訂内容の確認も自分たちで引き受けます。
通常の依存パッケージより手間は増えますが、方針の強いLintルールでは、コードを所有できることが利点になります。
- ルールが何を検出しているか、実装まで読める
- チーム固有の例外を追加できる
- ルール変更を通常のコードレビューに載せられる
- 上流の変更を、確認してから取り込める
一方、OxlintのAPI変更への追従、上流の改善取り込み、独自変更のテストも導入側の仕事になります。
vendoringは「依存関係をなくす仕組み」ではありません。ルールの決定権と保守責任を、同時に自分たちへ移す方法です。
15ルールは同じ種類ではない
anti-slopの15ルールを一括して「型安全ルール」と考えるのは適切ではなさそうです。大まかには、次のように性質が異なります。
| 分類 | 主なルール | 導入時に確認すること |
|---|---|---|
| 型の根拠を保つ | no-chained-type-assertions、no-known-value-widening、no-widen-then-assert、require-safety-comment-for-type-assertion | 型アサーションと広い型注釈の扱い |
| 境界を明確にする | no-unknown-parameters、no-unknown-returns、no-unknown-type-aliases、no-unsafe-dictionary-type、no-runtime-typeof | 外部入力をどこで検証するか |
| 動的アクセスを避ける | no-reflect-get、no-reflect-apply、no-object-parameters | メタプログラミングや汎用APIが必要か |
| テスト設計を変える | no-module-mocking | 既存テストがモジュールモックへ依存していないか |
| 記法・命名を制約する | no-conditional-empty-object-spread、no-shape-in-symbol-names | チームの表現方針と一致するか |
特にno-module-mockingは、型に関するルールと分けて判断するのがよいでしょう。
モジュールモックとは、テスト中にimport先のモジュールを別の実装へ差し替える方法です。Vitestのvi.mockやJestのjest.mockが代表例です。
舞台にたとえると、本来の共演者を舞台裏で別人へ入れ替えてから演技を確認する方法に近いものです。手軽ではありますが、主役が誰と組んでいるのかが台本から見えにくくなる場合があります。
anti-slopは、Vitest/Jestのグローバル参照、または正規のimportを通じたvi.mockやjest.mockを拒否します。その代わり、依存を関数の引数やコンストラクタから明示的に渡し、テスト時にはそこへ代替実装を渡せる設計を促します。
ただし、ローカルで作った同名のviオブジェクトまでは拒否しません。
const vi = { mock() {} };
vi.mock(); // no-module-mockingの対象外名前だけで判定するのではなく、Vitest/Jest由来の参照かを識別しています。
既存テストがモジュールモックへ依存している場合、no-module-mockingの導入はLint設定の追加にとどまりません。依存を外から渡す設計やテストの組み立て方にも影響します。そのため、型関連のルールとは別の変更として扱う方が、影響範囲を見積もりやすくなります。
15ルールは、同じ判断を求めていない
anti-slopの15ルールを一括で有効にすると、型の書き方、外部入力の扱い、テストの設計という別々の判断が同時に入ります。導入前に、何を変えるルールなのかを分けて考えます。
1. 型の根拠を残す
二重の型アサーションや、具体的に分かっている値を広い型へ戻す書き方を止めます。まずここから入れると、型を通すためだけのキャストを減らせます。
2. 外部入力は境界で扱う
unknownを引数や戻り値として広げる書き方、実行時のtypeofへ頼る書き方を制約します。APIやフォームの値を受け取る場所で検証する設計がすでにあるチームでは、導入しやすい領域です。境界検証が未整備なら、先にその入口を決めます。
3. テストの作り方も変わる
no-module-mockingはVitestやJestのモジュールモックを禁止します。モックを多用しているプロジェクトへ型関連のルールと同時に入れると、Lint導入ではなくテスト設計の変更になります。このルールは分けて判断します。
4. ルールは自分たちのリポジトリで管理する
付属Skillはanti-slopのコードをtools/oxlint/anti-slop/へコピーし、15ルールをerrorとして設定します。導入後は、ルールの更新も通常のコード変更と同じように差分レビューします。
最初は「型の根拠を残す」ルールだけを小さな範囲で有効にします。境界関連のルールは入力検証の方針を決めてから、モジュールモック禁止はテスト設計を見直せるときに追加します。
いきなり全ルールを有効にしない
付属Skillは15ルールすべてをerrorとして設定します。既存プロジェクトでは、全ルールを一度に必須化しません。違反の内容と修正差分を確認しながら、段階的に増やします。

1. まず違反を観測する
対象ディレクトリを限定し、初回の違反を次の4種類へ分類します。
- 不具合につながり得る
- 保守上の根拠を明確にする
- 現在のチーム方針と衝突する
- 誤検知、または修正価値が低い
件数だけでは、ルールが役立っているか判断できません。修正後のコードが読みやすくなったか、実行時の検証が適切な場所へ移ったかまで確認します。
2. 合意しやすいルールから始める
最初の候補として検討しやすいのは、次の4つです。
no-chained-type-assertions
no-known-value-widening
no-widen-then-assert
require-safety-comment-for-type-assertion
いずれも「型情報を捨てない」「例外の理由を残す」という目的を説明しやすく、既存のレビュー基準へ接続しやすいルールです。
まず少数のファイルで動かし、実際の診断と修正差分を見ます。チームのレビュー基準を改善するものだけを残します。
3. 境界関連のルールは入力検証方式と一緒に決める
unknownやtypeofを禁止するだけでは、別の型アサーションへ問題が移ります。スキーマ、型ガード、専用パーサーのどれを使うか決めてから有効にします。
例外を設ける場合も、単にLintを通すためではなく、「この場所で値を検証する」という方針を先に決めます。
4. モジュールモック禁止は別の設計変更として扱う
no-module-mockingは、テスト戦略へ影響します。既存テストの書き換え量、依存を外から渡す方法、テスト速度を確認してから判断します。
型アサーションを減らす変更と、テスト構造を変える変更を分ければ、レビューもしやすくなります。
5. 修正diffを見てからCIへ昇格する
違反が消えたことより、修正後のコードが理解しやすくなったかを重視します。Lintを黙らせるための機械的な言い換えが増えるなら、そのルールは必須化しません。
小さな範囲で修正前後を比較し、納得できたルールだけをCIの必須条件へ昇格させます。
導入が向いているプロジェクト
次の条件が多く当てはまる場合、anti-slopを試す価値があります。
- TypeScriptの型推論を積極的に残したい
- 外部入力をスキーマや専用パーサーで検証している
- 型アサーションには安全性の理由を求めたい
- 人とAI生成コードへ同じCI基準を適用したい
- vendoredコードをレビューし、保守する担当者がいる
- 新規プロジェクト、または段階的にLintを強化できる
反対に、次の条件では影響を丁寧に確認した方がよいでしょう。
unknownを中心にした既存APIが広く使われている
- モジュールモックに依存したテストが多い
- 動的アクセスやメタプログラミングが主要な設計である
- Oxlintとvendoredプラグインを保守する余力がない
- ルール違反を別の型アサーションで隠すだけになりそう
問うべきなのはツールの優劣ではなく、anti-slopの設計思想と既存プロジェクトの方針が合うかどうかです。
anti-slopの価値は「厳しさ」ではない
anti-slopの導入メリットは、禁止事項を増やせることではありません。
重要なのは、これまでレビュー担当者の頭の中にしかなかった判断を、コードとCIへ移せることです。
- その型を信用できる根拠はどこにあるか
- 外部入力はどこで検証済みになったか
- 型情報を途中で捨てていないか
- 例外を認めるなら、何を確認したのか
anti-slopの価値は、レビューで繰り返す問いをLintルールとして共有できることです。
まずは型の根拠を残すルールから導入し、違反と修正diffを確認します。コードの理由が読み取りやすくなるルールだけを必須化し、PRで守るなら対応するCIジョブをrequired status checkに設定します。
厳しいルールを増やすことが目的ではありません。型を信じる根拠を、レビュー担当者の記憶ではなく、コードと自動チェックに残すことが目的です。
エンジニアを募集しています!
ここまで読んでいただきありがとうございました!
Algomatic では、「AI革命で人々を幸せにする」をミッションに、変化の速い領域でも 学びや試行錯誤を続けられる エンジニアを募集しています。
もし少しでもご興味をお持ちいただけましたら、カジュアル面談に足を運んでいただけるとうれしいです!
Sources
- anti-slop公式リポジトリ: https://github.com/dmmulroy/anti-slop
- 検証スクリプトを含むpackage.json: https://github.com/dmmulroy/anti-slop/blob/main/package.json
- Oxlint公式ドキュメント: https://oxc.rs/docs/guide/usage/linter.html
- Oxlint JavaScriptプラグイン: https://oxc.rs/docs/guide/usage/linter/js-plugins.html
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み