mcpField
D
different-variables-types

different-variables-types

github.com/marius-townhouse開発643 回インストール38 週間前に更新
リポジトリ

different-variables-types について

異なる概念には別々の変数を使い、変数名の再利用やユニオン型による型の拡張を避けるよう勧める TypeScript スキルです。意図を明確にし、型と推論をシンプルに保ちます。

主な機能

  1. 01用途ごとに変数を分ける
  2. 02無関係な値のユニオン型を避ける
  3. 03可能な場合は const を使う
  4. 04意味に沿った変数名
  5. 05型の絞り込みと拡張の区別

活用シーン

  1. 01再代入による型エラーの解消
  2. 02型の異なる値の分離
  3. 03ユニオン型を使うコードの簡素化
  4. 04一時的な結果に再利用する変数の明確化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/marius-townhouse/effective-typescript-skills --skill different-variables-types

インストール後、Claude Code で/different-variables-typesを入力して読み込まれたか確認します。

詳細

異なる型には異なる変数を使う

概要

異なる目的で変数を使い回さないでください。

JavaScript では、どの変数にも任意の値を代入できます。しかし、TypeScript では、変数の型は一般に固定されています。異なる概念には異なる変数を使うことで、型安全性とコードの明瞭さが向上します。

このスキルを使う場面

  • 異なる目的で同じ変数名を使い回す場合
  • 異なる型の値が変数に代入される場合
  • 再代入に対応するためだけにユニオン型を使う場合
  • 変数の使い回しが原因の型エラーをデバッグする場合

絶対に守るルール

One variable, one type, one purpose.
Different concepts deserve different names.

覚えておきましょう:

  • 変数の値は変わっても、型は一般に変わりません
  • ユニオン型は単純な型より扱いにくいものです
  • const は let より適しています
  • 異なる名前を使うことで、意図が伝わります

検出:使い回しによる型エラー

let productId = "12-34-56";
fetchProduct(productId);  // Expects string

productId = 123456;
// ~~~~~~~ Type 'number' is not assignable to type 'string'

fetchProductBySerialNumber(productId);
// Expects number

TypeScript は、最初の代入から productId の型を string と推論します。

ユニオン型での「修正」(問題があります)

// Works, but creates problems
let productId: string | number = "12-34-56";
fetchProduct(productId);

productId = 123456;  // OK
fetchProductBySerialNumber(productId);  // OK

// But now everywhere you use productId, you need type guards:
if (typeof productId === 'string') {
  // ...
}

ユニオン型は扱いにくく、コードの意図を分かりにくくします。

より良い解決策:異なる変数を使う

const productId = "12-34-56";
fetchProduct(productId);

const serial = 123456;
fetchProductBySerialNumber(serial);

メリット:

  • 無関係な概念を切り分けられます
  • より具体的な変数名を使えます
  • 型推論が向上します(型注釈が不要になります)
  • 型が単純になります(ユニオン型ではありません)
  • 変数を const にできます

const がより適している理由

// let: type can be reassigned
let x = 'hello';
x = 'goodbye';  // OK
x = 42;         // Error: different type

// const: value cannot change
const y = 'hello';
y = 'goodbye';  // Error: cannot reassign const
// No type ambiguity ever

const を使うと、人にも TypeScript にも理解しやすいコードになります。

シャドーイング:別の問題

const productId = "12-34-56";
fetchProduct(productId);

{
  const productId = 123456;  // Different variable, same name
  fetchProductBySerialNumber(productId);
}

異なるスコープにある別々の変数なので、これは動作します。しかし、人には分かりにくいため、代わりに異なる名前を使うことをお勧めします。

型の絞り込みと変数の使い回し

TypeScript では、型を絞り込む(より具体的にする)ことができます。

let x: string | number = getValue();

if (typeof x === 'string') {
  x  // Type: string (narrowed)
  x.toUpperCase();  // OK
}

型を広げる(より具体性を下げる)ことはこれとは異なり、機能しません。

let x = 'hello';  // Type: string
x = 42;  // Error: can't widen to string | number

実際の例

// Bad: reusing 'result' for different things
let result = await fetchUser(id);
processUser(result);

result = await fetchPosts(id);  // Error: different type!
processPosts(result);

// Good: descriptive names for each
const user = await fetchUser(id);
processUser(user);

const posts = await fetchPosts(id);
processPosts(posts);

圧力への対処プロトコル

1. 「変数を使い回したい」

圧力:「一時的なものだから、再代入するだけです」

回答: 新しい変数を使いましょう。そのほうが明確で、型安全です。

対応: 説明的な名前を付けた新しい const を作成します。

2. 「ユニオン型で問題ない」

圧力:「string | number を使えばいいだけです」

回答: ユニオン型を使うと、その変数を使うあらゆる箇所が複雑になります。

対応: 単純な型を持つ別々の変数のほうが、扱いやすくなります。

危険信号 — 立ち止まって再検討しましょう

  • A と B が異なる目的で使われるのに、let x: A | B としている
  • まったく異なる値に再代入される変数
  • 再代入による型エラー
  • temp や result のような汎用的な変数名を使い回している

よくある正当化(すべて誤りです)

言い訳実際
「変数を節約できます」変数は安価ですが、バグは高くつきます
「同じデータで、形式が違うだけです」形式が違うなら、変数も分けましょう
「コードが少なくなります」コードの少なさより、明瞭さが大切です

クイックリファレンス

// DON'T: Reuse variable for different purposes
let id = "abc";
fetchByString(id);
id = 123;  // Error

// DON'T: Use union just to allow reassignment
let id: string | number = "abc";

// DO: Different variables for different concepts
const stringId = "abc";
const numericId = 123;

要点

異なる概念には、それぞれ異なる変数を使いましょう。

TypeScript の型は(絞り込みを除いて)変わりません。目的ごとに別々の変数を使うことで、この性質を活用しましょう。コードが明確になり、型が単純になり、バグも減ります。

参考資料

Dan Vanderkam 著『Effective TypeScript』の項目 19「異なる型には異なる変数を使う」に基づいています。

コメント