TypeScript | 基礎文法:変数・基本型 – 明示型と推論型の使い分け

TypeScript
スポンサーリンク

「明示型」と「推論型」とは何か

TypeScriptには、型を扱う2つのスタイルがあります。
ひとつは「明示型」——自分で : string: number のように型を書いて宣言するやり方。
もうひとつは「推論型」——TypeScriptに「この値から型を判断して」と任せるやり方です。

// 明示型(explicit typing)
let age: number = 20;

// 推論型(type inference)
let score = 80; // TypeScript が number と推論
TypeScript

どちらも最終的には「age は number」「score も number」として扱われます。
違うのは、「人間が型を書くか」「コンパイラが型を決めるか」です。


明示型を使うべき典型的な場所

関数の引数と戻り値

関数の引数と戻り値は、「明示型」を強くおすすめする領域です。

function add(a: number, b: number): number {
  return a + b;
}
TypeScript

ここで大事なのは、コードを読むだけで「この関数は number を2つ受け取って、number を返す」と一目で分かること。
これは「設計の約束」を型で表現している状態です。

もし引数に型を書かないと、strict でなければ any になり、型安全性が一気に崩れます。
関数は「外から呼ばれる窓口」なので、ここを曖昧にすると、バグが入り込む余地が一気に増えます。

オブジェクトリテラルや重要な構造

ユーザー情報や設定など、「形が重要なオブジェクト」にも明示型を付ける価値が高いです。

type User = {
  id: number;
  name: string;
  email: string;
};

const user: User = {
  id: 1,
  name: "Taro",
  email: "taro@example.com"
};
TypeScript

こうしておくと、email を書き忘れたり、id に string を入れたりした瞬間にエラーになります。
「このオブジェクトはこういう形であるべき」という設計を、型として固定できるのが明示型の強みです。


推論型に任せていい場所

シンプルなローカル変数

一方で、すべてに : 型 と書く必要はありません。
特に、関数の中の「その場で完結するローカル変数」は、推論に任せた方が読みやすくなることが多いです。

const price = 1000;      // number と推論
const taxRate = 0.1;     // number と推論
const total = price * (1 + taxRate); // number と推論
TypeScript

ここにわざわざ : number を全部書くと、情報量は増えますが、目線としては「もう分かってるよ」というノイズにもなりがちです。

TypeScript公式も、「初期化される変数やメンバー、デフォルト引数、戻り値などは、多くの場合推論で十分」と説明しています。

文脈から明らかなとき

たとえば、配列リテラルも中身から型が推論されます。

const scores = [80, 90, 100];      // number[] と推論
const names = ["Taro", "Hanako"];  // string[] と推論
TypeScript

「全部数値」「全部文字列」と一目で分かる場面では、推論に任せてもコードの意図は十分伝わります。


明示型と推論型の「役割分担」の考え方

設計を表現したいところは明示型

ポイントは、「どこに“設計の意図”を刻みたいか」です。

関数の引数・戻り値
外部との境界(APIレスポンス、ライブラリとのやり取り)
ドメイン的に重要な型(User, Product, Config など)

こういう場所は、「この型であるべきだ」という意図を明示的に書いた方が、未来の自分や他人にとって圧倒的に読みやすくなります。

type ProductId = number;

function getProduct(id: ProductId): Promise<Product> {
  // ...
}
TypeScript

ここで id: ProductId と書いておくと、「ただの number じゃなくて、プロダクトIDなんだな」と分かります。
こういう「意味のある型」は、推論に任せず、明示的に書いた方が設計が伝わります。

実装の細部は推論に任せてスッキリさせる

逆に、関数の中の一時変数や、中間計算の結果など、「外から見えない実装の細部」は、推論に任せてしまって構いません。

function calcTotal(price: number, taxRate: number): number {
  const tax = price * taxRate;      // number と推論
  const total = price + tax;        // number と推論
  return total;
}
TypeScript

ここで tax: numbertotal: number と書いても間違いではありませんが、推論に任せた方がコードが軽くなり、「何をしているか」に集中しやすくなります。


「任せすぎる」と何が起きるか

any に落ちてしまう危険

推論に任せるときに一番怖いのは、「気づかないうちに any になっている」パターンです。

function greet(name) {
  return `Hello, ${name}`;
}
TypeScript

引数に型を書かないと、strict でなければ name は any になります。
any は「何でも入るし、何でもできる」代わりに、型チェックが効かなくなる危険な存在です。

なので、特に関数の引数は「推論に任せない」「必ず明示型を書く」と決めてしまった方が安全です。


初心者向けの実践ルール

最後に、現場でもそのまま通用するシンプルな指針をまとめると、こんな感じです。

関数の引数と戻り値:必ず明示型を書く。
オブジェクトの型(User, Product など):型エイリアスやinterfaceで明示的に定義する。
ローカル変数(関数の中):初期値がはっきりしているなら推論に任せてOK。
「意味を伝えたい場所」:明示型で意図を刻む。
「見れば分かる場所」:推論でコードを軽くする。

このバランスが取れてくると、
「型がうるさい」ではなく「型が設計を支えてくれている」感覚に変わっていきます。

タイトルとURLをコピーしました