MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
TypeScriptの基礎 - 関数の型定義のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
TypeScriptの基礎 - 関数の型定義
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == TypeScriptにおける関数の型定義とは、関数のパラメータと戻り値に対して型を明示する仕組みである。<br> JavaScriptの関数と比べ、TypeScriptの型情報によってコンパイル時に誤った引数の渡し方や戻り値の誤用を検出できる。<br> <br> * 関数の型注釈 *: 関数宣言、関数式、アロー関数におけるパラメータと戻り値の型注釈の記述方法 *: <code>void</code> (値を返さない) と <code>never</code> (終端に到達しない) の使い分け * パラメータの柔軟な定義 *: オプショナル引数 (<code>?</code>)、デフォルト引数 (<code>= 値</code>)、レストパラメータ (<code>...args</code>) による柔軟な関数シグネチャ *: TypeScript 4.0以降ではタプル型をレストパラメータに使用でき、引数の数と各位置の型を厳密に指定できる * 関数のオーバーロード *: 同名の関数に複数の型シグネチャを定義し、引数の型に応じた異なる戻り値型を提供する * コールバック関数と関数型 *: インラインまたは <code>type</code> / <code>interface</code> を用いたコールバック関数の型定義パターン *: コールバックの戻り値型には <code>any</code> ではなく <code>void</code> の使用が推奨される <br> TypeScript 4.9で導入された <code>satisfies</code> 演算子を使用すると、関数を含むオブジェクトが特定の型を満たすことを検証しつつ、具体的な型情報を保持できる。<br> TypeScript 5.4の <code>NoInfer</code> ユーティリティ型により、ジェネリック関数においてどのパラメータから型を推論するかを明示的に制御できるようになった。<br> <br> 2026年2月時点でTypeScript 5.9が安定版としてリリースされている。<br> TypeScript 6.0ベータでは <u>strict: true</u> や <u>module: "esnext"</u> のデフォルト化等の変更が行われており、Go言語で書き直されるTypeScript 7.0では最大10倍のコンパイル速度向上が見込まれている。<br> <br><br> == 関数の型注釈 == TypeScriptでは、関数のパラメータと戻り値に対して型注釈を記述できる。<br> <br> パラメータの型注釈はパラメータ名の直後にコロンと型名を記述し、戻り値の型注釈はパラメータリストの閉じ括弧の後に記述する。<br> <br> ==== 関数宣言 ==== <code>function</code> キーワードを使用した関数宣言では、パラメータと戻り値にそれぞれ型注釈を付与する。<br> <br> 基本的な構文は以下の通りである。<br> <br> <syntaxhighlight lang="typescript"> function <関数名>(<パラメータ>: <型>): <戻り値の型> { // 処理 } </syntaxhighlight> <br> 具体的な例を以下に示す。<br> <br> <syntaxhighlight lang="typescript"> function greet(name: string): void { console.log("Hello, " + name.toUpperCase() + "!!"); } function add(a: number, b: number): number { return a + b; } function getFavoriteNumber(): number { return 26; } </syntaxhighlight> <br> <u>TypeScriptはreturn文から戻り値の型を推論できるため、戻り値の型注釈を省略しても型安全性は保たれる場合がある。</u><br> <br> <u>ただし、公開APIや複雑な関数では、意図を明示し意図しない変更を防ぐために戻り値の型注釈を記述することが推奨される。</u><br> <br> ==== 関数式とアロー関数 ==== 関数式やアロー関数においても、パラメータと戻り値に型注釈を付与できる。<br> <br> 型注釈の記述方法には、変数に対して型を付与するパターンと、関数本体に対して型を付与するパターンの2種類がある。<br> <br> 関数式において変数に型注釈を付与する場合は以下の通りである。<br> <br> <syntaxhighlight lang="typescript"> // パターン1 : 変数に型注釈を付与する let fn: (param1: string, param2: number) => string = function(param1, param2) { return param1 + param2; }; // パターン2 : 関数本体に型注釈を付与する let fn2 = function(param1: string, param2: number): string { return param1 + param2; }; </syntaxhighlight> <br> アロー関数における型注釈の例を以下に示す。<br> <br> <syntaxhighlight lang="typescript"> const add = (a: number, b: number): number => { return a + b; }; const callback: (value: string) => void = (value) => { console.log(value); }; </syntaxhighlight> <br> パターン1の記述では、変数に型を付与することで型情報とロジックが分離される。<br> <br> パターン2の記述では、実装と型注釈が近い位置に記述されるため、ソースコードの可読性が高まる場合がある。<br> <br> ==== voidとnever ==== TypeScriptには、関数の戻り値として特別な意味を持つ <code>void</code> 型と <code>never</code> 型がある。<br> これらは似ているようで異なる用途を持つ。<br> <br> ===== void型 ===== <code>void</code> 型は、関数が値を返さないことを表す戻り値型である。<br> 戻り値が不要な関数やコールバック関数の戻り値を意図的に無視する場合に使用する。<br> <br> <syntaxhighlight lang="typescript"> function printValue(): void { console.log("Hello"); } </syntaxhighlight> <br> コールバック関数の戻り値の型に <code>void</code> を使用する場合、コールバックがどのような値を返しても型エラーにならない。<br> <u><code>any</code> を使用すると戻り値が誤用される実行時エラーが発生する可能性があるため、コールバックの戻り値型には <code>void</code> を使用することが推奨される。</u><br> <br> <syntaxhighlight lang="typescript"> // コールバックの戻り値を無視する場合はvoidを使用する function fn(x: () => void) { x(); } </syntaxhighlight> <br> ===== never型 ===== <code>never</code> 型は、関数が正常に値を返すことがない場合の戻り値型である。<br> 関数の終端に到達しないことを型レベルで示す。<br> <br> 下表に、<code>never</code> 型が使用される主なケースを示す。<br> <br> <center> {| class="wikitable" |+ never型の主な使用場面 ! 場面 !! 説明 |- | 例外をスローする関数 || 必ず、<code>throw</code> を実行するため、return文に到達しない。 |- | 無限ループを含む関数 || ループが終了しないため、関数の終端に到達しない。 |- | 到達不可能なコードパスの検出<br>(exhaustive checking) || switch文のdefault節に <code>never</code> 型の変数を置くことにより、<br>型の網羅性をコンパイル時に検証する。 |} </center> <br> <syntaxhighlight lang="typescript"> function error(message: string): never { throw new Error(message); } function infiniteLoop(): never { while (true) {} } </syntaxhighlight> <br> exhaustive checkingの活用例を以下に示す。<br> <code>Shape</code> 型に新しいケースが追加された時、<code>default</code> 節で <code>never</code> 型への代入がコンパイルエラーとなり、処理の追加漏れを確実に検出できる。<br> <br> <syntaxhighlight lang="typescript"> type Shape = Circle | Square; function getArea(shape: Shape) { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "square": return shape.sideLength ** 2; default: const _exhaustiveCheck: never = shape; return _exhaustiveCheck; } } </syntaxhighlight> <br> 下表に、<code>void</code> と <code>never</code> の違いを示す。<br> <br> <center> {| class="wikitable" |+ void と never の比較 ! 特性 !! void !! never |- | 関数の性質 || 値を返さない (正常終了) || 終端に到達しない。 |- | 戻り値 || undefined || 値を返す文がない。 |- | 使用シーン || 通常の処理完了後に値が不要 || 例外送出または無限ループ |} </center> <br><br> == オプショナル引数とデフォルト引数 == TypeScriptでは、パラメータを省略可能にしたり、省略時のデフォルト値を設定したりできる。<br> <br> ==== オプショナル引数 ==== パラメータ名の直後に <code>?</code> を付与することにより、呼び出し時にそのパラメータを省略できる。<br> 省略した場合、そのパラメータの値は <u>undefined</u> になる。<br> <br> オプショナル引数は、必須引数の後に配置する必要がある。<br> <br> <syntaxhighlight lang="typescript"> function greet(name: string, greeting?: string): string { return (greeting || "Hello") + ", " + name; } greet("Alice"); // OK : greetingはundefined greet("Alice", "Hi"); // OK : greetingは"Hi" </syntaxhighlight> <br> <u>関数内でオプショナル引数を使用する場合は、<code>undefined</code> になる可能性を考慮して処理を記述する。</u><br> <br> ==== デフォルト引数 ==== パラメータに <code>= 値</code> の形式でデフォルト値を設定できる。<br> <br> 呼び出し時にそのパラメータを省略すると、デフォルト値が使用される。<br> デフォルト値が指定されている場合、TypeScriptは値から型を推論するため、型注釈を省略できる。<br> <br> <syntaxhighlight lang="typescript"> function greet(name: string, greeting: string = "Hello"): string { return greeting + ", " + name; } greet("Alice"); // "Hello, Alice" greet("Alice", "Hi"); // "Hi, Alice" </syntaxhighlight> <br> 分割代入 (Destructuring) の引数にもデフォルト値を設定できる。<br> <br> <syntaxhighlight lang="typescript"> type PaintOptions = { shape: string; xPos?: number; yPos?: number; }; function paintShape({ shape, xPos = 0, yPos = 0 }: PaintOptions) { console.log("x coordinate at", xPos); console.log("y coordinate at", yPos); } </syntaxhighlight> <br><br> == レストパラメータ == レストパラメータを使用すると、可変長の引数を配列として受け取ることができる。<br> <br> パラメータ名の前に <code>...</code> を付与し、型には配列型を指定する。<br> レストパラメータは、関数のパラメータリストの最後に配置する必要がある。<br> <br> <syntaxhighlight lang="typescript"> function sum(...numbers: number[]): number { return numbers.reduce((a, b) => a + b, 0); } sum(1, 2, 3); // 6 sum(1, 2, 3, 4, 5); // 15 </syntaxhighlight> <br> TypeScript 4.0以降では、タプル型をレストパラメータに使用できる。<br> タプル型を使用することにより、引数の数と各位置の型を厳密に指定できる。<br> <br> <syntaxhighlight lang="typescript"> function foo(...args: [string, number]): void { const [name, age] = args; console.log(`${name} is ${age} years old`); } foo("Alice", 30); // OK foo("Alice"); // エラー : Expected 2 arguments, but got 1. </syntaxhighlight> <br><br> == 関数のオーバーロード == TypeScriptの関数オーバーロードは、同名の関数に複数の型シグネチャを定義する機能である。<br> 呼び出し元に対して、引数の型に応じた異なる戻り値の型を提供できる。<br> <br> 関数オーバーロードは、<u>オーバーロードシグネチャ</u> と <u>実装シグネチャ</u> の2つで構成される。<br> <br> <center> {| class="wikitable" |+ 関数オーバーロードのシグネチャの種類 ! シグネチャ !! 説明 |- | オーバーロードシグネチャ || 呼び出し側から見える型定義<br>関数本体 (実装) を持たない。 |- | 実装シグネチャ || 実際の処理を含む関数定義<br>外部から直接呼び出すことはできない。 |} </center> <br> <syntaxhighlight lang="typescript"> // オーバーロードシグネチャ function printValue(str: string): void; function printValue(num: number, maxFractionDigits?: number): void; // 実装シグネチャ function printValue(value: string | number, maximumFractionDigits?: number) { if (typeof value === "number") { const formatter = Intl.NumberFormat("en-US", { maximumFractionDigits, }); value = formatter.format(value); } console.log(value); } printValue("Hello"); // OK printValue(3.14159, 2); // OK </syntaxhighlight> <br> 関数オーバーロードを記述する際の重要なルールを以下に示す。<br> * オーバーロードシグネチャは、より具体的な型から一般的な型の順に記述する。 * 実装シグネチャは全てのオーバーロードシグネチャと互換性を持つ必要がある。 * 実装シグネチャは外部から直接呼び出すことができない。 <br> <u>オーバーロードを使用する場面が複雑になる場合は、ユニオン型を使用した単一の関数定義で代替できることも多い。</u><br> <br><br> == コールバック関数の型定義 == TypeScriptでは、コールバック関数の型を明示的に定義することにより、コールバックの引数と戻り値の型安全性を確保できる。<br> <br> ==== インラインでの型定義 ==== コールバックを受け取るパラメータに対して、直接型を記述する方法である。<br> <br> <syntaxhighlight lang="typescript"> function processData(callback: (value: string) => void) { const result = "processed"; callback(result); } </syntaxhighlight> <br> ==== 型エイリアスを使用した型定義 ==== <code>type</code> キーワードでコールバック関数の型に名前を付けることにより、再利用性を高め、ソースコードの可読性を向上させることができる。<br> <br> <syntaxhighlight lang="typescript"> type StringCallback = (value: string) => void; function processData(callback: StringCallback) { const result = "processed"; callback(result); } </syntaxhighlight> <br> 複数のパラメータを持つコールバックの型定義例を以下に示す。<br> <br> <syntaxhighlight lang="typescript"> type EventCallback = (event: Event, context: string) => boolean; function on(event: string, callback: EventCallback): void { // イベント登録の処理 } </syntaxhighlight> <br> <u>コールバック関数の戻り値の型には <code>void</code> を使用することにより、コールバックがどのような値を返してもエラーにならない。</u><br> <br> <u><code>any</code> を使用すると戻り値が予期しない形で使用されるリスクがあるため、<code>void</code> の使用が推奨される。</u><br> <br><br> == 関数型の定義 == TypeScriptでは、<code>type</code> キーワード や <code>interface</code> キーワードを使用して、関数の型を独立して定義できる。<br> <br> 型に名前を付けることにより、複数の箇所で同じ関数型を再利用できる。<br> <br> ==== typeによる定義 ==== <code>type</code> キーワードを使用した関数型の定義は直感的で、関数型を表現する時に広く使用される方法である。<br> <br> <syntaxhighlight lang="typescript"> type Callback = (value: string) => void; type Add = (a: number, b: number) => number; type AsyncOperation = (data: unknown) => Promise<void>; const add: Add = (a, b) => a + b; </syntaxhighlight> <br> ジェネリック型と組み合わせることにより、汎用的な関数型を定義できる。<br> <br> <syntaxhighlight lang="typescript"> type Mapper<T, U> = (input: T) => U; type Filter<T> = (item: T) => boolean; const toLength: Mapper<string, number> = (s) => s.length; const isEven: Filter<number> = (n) => n % 2 === 0; </syntaxhighlight> <br> async関数は常に <code>Promise</code> 型を返すため、戻り値の型に <code>Promise<T></code> を指定する。<br> <br> <syntaxhighlight lang="typescript"> async function fetchData(): Promise<string> { const response = await fetch("/api/data"); return response.text(); } const asyncArrow = async (): Promise<number> => { return 42; }; </syntaxhighlight> <br> ==== interfaceによる定義 ==== <code>interface</code> キーワードを使用して関数型を定義する場合は、call signatureを用いる構文を使用する。<br> <br> <syntaxhighlight lang="typescript"> interface StringCallback { (value: string): void; } const myCallback: StringCallback = (value) => { console.log(value); }; </syntaxhighlight> <br> ジェネリックインターフェースとして定義することもできる。<br> <br> <syntaxhighlight lang="typescript"> interface Mapper<T, U> { (input: T): U; } const stringify: Mapper<number, string> = (n) => String(n); </syntaxhighlight> <br> 関数型の定義には <code>type</code> を使用する方が構文的に直感的である。<br> <br> <code>interface</code> はオブジェクトの構造定義に使用するのが適切であり、関数型の定義には <code>type</code> を優先することが推奨される。<br> <br> <code>type</code> と <code>interface</code> の詳細な使い分けについては、<br> [[TypeScriptの基礎 - 型エイリアス]] および [[TypeScriptの基礎 - オブジェクト型とインターフェース]]のページを参照すること。<br> <br><br> == 関連情報 == * [[TypeScriptの基礎 - tsconfig.json]] * [[TypeScriptの基礎 - 型注釈とプリミティブ型]] * [[TypeScriptの基礎 - 型推論]] * [[TypeScriptの基礎 - オブジェクト型とインターフェース]] * [[TypeScriptの基礎 - 型エイリアス]] <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Rust]][[カテゴリ:Web]]
TypeScriptの基礎 - 関数の型定義
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse