TypeScript | 基礎文法:関数の基礎 – アロー関数の型

JavaScript
スポンサーリンク

アロー関数でも「型の考え方」は普通の関数と同じ

まず一番大事なところから。
アロー関数でも、「引数の型」と「戻り値の型」を決める考え方は、普通の function とまったく同じです。

// 通常の関数
function add(a: number, b: number): number {
  return a + b;
}

// アロー関数
const addArrow = (a: number, b: number): number => {
  return a + b;
};
TypeScript

違うのは書き方だけで、「何を約束しているか」は同じです。

(a: number, b: number): number => ...
この部分が「引数の型」と「戻り値の型」を表しています。

  • a: number, b: number … 引数はどちらも number
  • ): number … 戻り値は number

「アロー関数も、引数と戻り値の型を“かっこ”のところに書くだけ」
まずはこの感覚を持ってしまうと楽になります。


アロー関数の基本的な型の書き方

その1:変数に直接「引数型+戻り値型」を書くパターン

一番よく見る基本形です。

const greet = (name: string): string => {
  return `Hello, ${name}`;
};

const message = greet("Taro"); // message: string
// greet(123); // エラー: number は string に渡せない
TypeScript

ポイントは、

  • name: string … 引数の型
  • ): string … 戻り値の型

この2つを、=> の前に書くだけです。

その2:戻り値が明らかなときは型推論に任せる

TypeScript は戻り値型を推論してくれます。

const double = (n: number) => {
  return n * 2;
};
// 戻り値型は number と推論される
TypeScript
  • 学習中の小さな関数 → 戻り値型を省略してもOK
  • 実務での共通関数・複雑な関数 → 戻り値型を書いた方が安全

という使い分けで考えるとよいです。


アロー関数に「関数型」を先に付けてから中身を書くスタイル

その1:変数に関数型を付けてから代入する

アロー関数の型で、実務でよく使われるパターンがこれです。

type Add = (a: number, b: number) => number;

const add: Add = (a, b) => {
  return a + b;
};
TypeScript

ここでは、

  • type Add = (a: number, b: number) => number; → 「2つの number を受け取り、number を返す関数型」
  • const add: Add = ...; → 「add は Add 型の関数ですよ」と宣言

という流れになっています。

この書き方のメリットは、

  • 関数の「形」を別名(Add)として再利用できる
  • 引数名を変えても型エラーにならない(位置と型だけ合っていればよい)
const add2: Add = (x, y) => x + y; // OK(名前は違ってもいい)
TypeScript

「まず関数の“型”を定義して、それに沿うアロー関数を書く」
この考え方を持っておくと、大きなコードでも整理しやすくなります。

その2:インラインで関数型を書く

わざわざ type 名を作らず、その場で関数型を書くこともできます。

const add: (a: number, b: number) => number = (a, b) => {
  return a + b;
};
TypeScript
  • 左側の : (a: number, b: number) => number が「関数の型」
  • 右側が「その実装」

この書き方もよく出てくるので、「=> が2回出てきて混乱するかもしれないけど、左は型、右は実装」と覚えておくと安心です。


アロー関数をコールバックで使うときの型

引数側に型があるときは、アロー関数側は省略してよい

よくあるのは配列メソッドです。

const numbers = [1, 2, 3];

const doubled = numbers.map((n) => n * 2);
TypeScript

map の定義側が「このコールバックは (value: number) => 何か ですよ」と型を持っているので、
アロー関数側では n の型を省略しても、TypeScript が number と推論してくれます。

つまり、

numbers.map((n: number) => n * 2); // と書いてもOKだが、冗長
TypeScript

ということです。

「呼び出される側(map)が引数の型を知っているときは、渡す側(アロー関数)は型を省略できる」
これがコールバックでのよくあるパターンです。

自分でコールバックを受け取る関数を作る場合

自分で「関数を引数に取る関数」を作るときは、関数型をしっかり書きます。

type StringFn = (value: string) => void;

function process(fn: StringFn) {
  fn("hello");
}

process((v) => {
  console.log(v.toUpperCase()); // v は string と推論される
});
TypeScript
  • StringFn が「string を受け取って何も返さない関数型」
  • process は「StringFn 型の関数を受け取る」
  • 渡したアロー関数は「value が string であること」を自動で保証される

このパターンを何度か書いておくと、
「関数の型を先に決める → アロー関数で実装する」流れが自然になります。


アロー関数とオブジェクト・型エイリアスの組み合わせ

オブジェクトのメソッドとしてアロー関数を使う

こんな書き方もできます。

type Counter = {
  value: number;
  increment: (amount: number) => void;
};

const counter: Counter = {
  value: 0,
  increment: (amount) => {
    counter.value += amount;
  },
};

counter.increment(5);
TypeScript

ここでは、

  • type Counter に「increment は (amount: number) => void」という関数型を定義
  • counter オブジェクトで、その型に合うアロー関数を実装

という形になっています。

アロー関数の型を設計するときは、
「まず“こういう関数が欲しい”という形を type で書く → それに沿うアロー関数を書く」
この順番で考えると、設計の筋が通りやすくなります。


アロー関数の型を意識するうえでの「軸」

最後に、アロー関数+型をどう捉えるといいか、軸だけまとめます。

アロー関数も普通の関数と同じく、「引数の型」と「戻り値の型」の約束を書く場所がある。
小さな一時的な関数 → (arg: 型): 型 => { ... } をその場で書く。
再利用したい・コールバックとして何度も使いたい → type Fn = (arg: 型) => 型; を先に作ってから、アロー関数を代入する。
配列メソッドなど「呼び出される側」が型を持っているとき → アロー関数側の引数型は省略してOK(型推論に任せてよい)。

そして一番大事なのは、
「これは、どんな引数を受け取って、どんな値を返す関数なのか?」
そのイメージを、型として素直に書き下ろすことです。

アロー関数はただの「=> 記法」ではなく、
「その関数の“形”と“役割”を、短く・はっきり書き表すための道具」だと捉えてみてください。

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