型ヒントは、Python のコードに「期待する型」を書き添えるしくみです。本記事では基本の書き方から、OptionalTypedDict などのよく使うパターンを整理します。生成AI と一緒にコードを書くときにも、型ヒントは強い手がかりになります。

目次

  1. 型ヒントとは
  2. 基本の型
  3. Optional と Union — 値がないかもしれない
  4. Any — 何でも受ける(最後の手段)
  5. Callable — 関数を受け取る
  6. TypedDict — 辞書のキーごとに型を決める
  7. dataclass の型ヒント
  8. 型チェッカーで検査する
  9. 生成AI に読み書きしやすいコードのために
  10. やりすぎない

型ヒントとは

型ヒントは「この変数や関数の引数は何の型か」を書き添える記法です。

price: int = 1500
name: str = "トヨタ自動車"
prices: list[float] = [2900.0, 2925.0]
def average(values: list[float]) -> float:
return sum(values) / len(values)

押さえたいポイントは次の 2 つです。

  • 型ヒントは 実行時にチェックされない(注釈にすぎない)
  • ただし エディタや型チェッカーが活用 し、生成AI も意図を読み取りやすくなる

基本の型

組み込みの型はそのまま書けます。

i: int = 1
f: float = 1.5
s: str = "7203"
b: bool = True
n: None = None

コレクション型はカッコ [ ] の中に要素の型を書きます。Python 3.9 以降は組み込み型の小文字版がそのまま使えます。

prices: list[float] = [2900.0, 2925.0]
ohlc: tuple[float, float, float, float] = (2900, 2950, 2880, 2925)
tickers: set[str] = {"7203", "9984"}
companies: dict[str, str] = {"7203": "トヨタ自動車"}

タプルが「何でも入る」場合は tuple[float, ...]、辞書のキーや値が複合的なら dict[str, list[float]] のようにネストできます。

Optional と Union — 値がないかもしれない

「値があるか、なにもない(None)か」のどちらかを表すときは Optional を使います。

from typing import Optional
def find_price(ticker: str) -> Optional[float]:
return None # 見つからなければ None

Python 3.10 以降は | を使った書き方が推奨されています。

def find_price(ticker: str) -> float | None:
return None

複数の型を許容するときも同じです。

def parse(value: str | int) -> int:
return int(value)

Any — 何でも受ける(最後の手段)

どうしても型を絞れないときは Any を使います。ただし Any を多用すると型ヒントの効果がなくなるため、最後の手段として扱います。

from typing import Any
def first(values: list[Any]) -> Any:
return values[0]

Callable — 関数を受け取る

関数を引数として受け取る関数では、Callable で型を表します。

from typing import Callable
def apply(values: list[float], func: Callable[[float], float]) -> list[float]:
return [func(v) for v in values]
print(apply([1.0, 2.0, 3.0], lambda x: x * 2)) # [2.0, 4.0, 6.0]

Callable[[引数の型, ...], 戻り値の型] の形で書きます。

TypedDict — 辞書のキーごとに型を決める

「特定のキーがある辞書」を表したいときは TypedDict を使います。API レスポンスや CSV の 1 行などを表すのに便利です。

from typing import TypedDict
class StockRow(TypedDict):
Date: str
Code: str
C: int
Vo: int
row: StockRow = {
"Date": "2026-04-01",
"Code": "7203",
"C": 2900,
"Vo": 11_000_000,
}

row["C"] のとき、エディタが型を int と認識してくれます。

dataclass の型ヒント

dataclass のフィールドはそのまま型ヒントです(#3-5「クラスの最低限」 で扱いました)。

from dataclasses import dataclass
@dataclass
class Stock:
ticker: str
name: str
prices: list[float]
s = Stock(ticker="7203", name="トヨタ自動車", prices=[2900.0, 2925.0])

データ構造を表したい場面では、TypedDict よりも dataclass のほうが扱いやすいことが多いです。

型チェッカーで検査する

型ヒントを書いただけでは実行時に検査されません。mypypyright といった 型チェッカー で確認します。

Terminal window
pip install mypy
mypy your_module.py

型ヒントと実装の不整合を、実行前に検出できます。

def average(values: list[float]) -> float:
return sum(values) / len(values)
# mypy: error: Argument 1 has incompatible type "list[str]"
print(average(["a", "b"]))

学習段階では必須ではありませんが、ある程度コードが育ってきたら導入する価値があります。

生成AI に読み書きしやすいコードのために

生成AI は型ヒントを 入力の手がかり として強く参照します。型ヒントを書いておくと、次のような効果があります。

  • 意図が伝わる: 引数や戻り値の意味を明示でき、ブレのないコードが返りやすい
  • 修正の精度が上がる: 既存コードの修正を頼んだとき、型を揃えた変更が返ってくる
  • 未使用パターンが減る: 「想定外の型を渡したらどうするか」を AI が考えやすい

「型ヒントを書く前提」でプロンプトを組むと、戻ってくるコードの精度が一段上がります。

やりすぎない

型ヒントは便利ですが、書きすぎは弊害もあります。

  • 複雑すぎる型 は型ヒント自体が読みづらくなる(dict[str, list[tuple[int, str]]] など)
  • 小さなスクリプト に厳格な型ヒントは必須ではない
  • 動的すぎる処理Any で逃げる柔軟さも必要

「ライブラリの公開関数や、データ構造の境界面に集中して書く」のが現実的な落とし所です。

生成AI へのプロンプト例

既存コードに型ヒントを付けるよう依頼する例です。

次の Python 関数に、Python 3.12 の構文で型ヒントを付けてください。
- 戻り値が None になり得る場合は str | None で明示する
- リストや辞書はネストした型まで具体化する
- TypedDict / dataclass を使ったほうが分かりやすい場合は提案する
def fetch_prices(ticker, start, end):
if not ticker:
return None
return [
{"Date": "2026-04-01", "C": 2900},
{"Date": "2026-04-02", "C": 2925},
]

「使っていい記法・使ってほしくない記法」を伝えると、想定どおりの結果に近づきます(#7-2「データ分析のためのプロンプト設計」)。

まとめ

  • 型ヒントは関数と変数に「期待する型」を書き添える記法
  • list[int] / dict[str, str] / float | None で多くのケースをカバーできる
  • 辞書の構造を表したいときは TypedDictdataclass
  • 型ヒントは生成AI への手がかりになる。書きすぎず、境界面を中心に付ける