TypeScriptのvoid型とunknown型をやさしく解説!初心者でもわかる使い分け
生徒
「TypeScriptでvoid型とunknown型って見かけるんですが、何が違うんですか?」
先生
「いい質問ですね。実は、この2つの型は使い方も意味も全然違うんですよ。」
生徒
「どっちを使えばいいのかよく分からないんです……」
先生
「それでは、void型とunknown型の違いや使い分けを、初心者向けにわかりやすく説明していきましょう!」
1. void型とは?関数が何も返さないときに使う
まずは、TypeScriptのvoid型について説明しましょう。void型は、主に関数の戻り値として使われます。意味は、その関数が値を返さないという宣言です。
「処理はするけれど、結果としてのデータはいらない」というときに使うイメージです。実際の開発でも、「画面に表示するだけ」「ログを出すだけ」といった関数はたくさん出てきます。
たとえば、画面にメッセージを表示するだけの関数では、何も戻ってこないのでvoid型を使います。
以下の例を見てください。
function showMessage(): void {
console.log("こんにちは、TypeScript!");
}
このshowMessage関数は、コンソールにメッセージを表示するだけで、「結果となる値」は返していません。そのため、戻り値の型としてvoidを指定します。
呼び出す側から見ると、「この関数を実行すると画面にメッセージは出るけれど、受け取る値はない」と理解できるので、コードを読む人にもわかりやすくなります。
showMessage(); // メッセージを表示するだけで、値は返ってこない
イメージとしては、「お手伝いを頼んだらやってくれるけれど、何かを持って返ってくるわけではない人」のようなものです。動きだけしてくれる関数に対して、void型を使うと覚えておくと、TypeScriptのコードがぐっと読みやすくなります。
2. unknown型とは?中身がまだ分からないときに使う
次に紹介するのはunknown型です。unknown型は、「中身はちゃんとあるけれど、今この時点ではその正体が分からない」ことを表す型です。
たとえば、Web画面から入力された値や、外部のAPIから受け取ったデータなど、どんな型が入ってくるか事前にははっきりしないケースがあります。文字列かもしれないし、数値かもしれないし、真偽値かもしれません。そういった「とりあえず受け取っておきたいけれど、型はまだ決められない」ようなデータに対して、unknown型を使います。
イメージとしては、「中身が入っている箱は届いたけれど、まだ開けていない状態」です。箱はある(=値はある)が、開けてみるまで中身は分からない、という感覚です。
let data: unknown;
data = "文字列";
data = 123;
data = true;
このように、unknown型にしておくと、文字列・数値・真偽値など、どんな型の値でもいったん受け取ることができます。TypeScriptの文法としてもエラーにならないので、「型が決まっていない入り口」のような役割を持たせられます。
ただし、ここが大事なポイントです。unknown型の値は、そのままでは中身を直接使えません。なぜなら、「文字列だと思ってメソッドを呼んだら、実は数値だった」というようなミスを防ぐために、TypeScriptが「本当にその型で合っている?」と確認を要求してくるからです。
そのため、unknown型の値を使うときは、まずtypeofなどを使って、中身の型をチェックしてから安全に扱うのが基本的な流れになります。
if (typeof data === "string") {
console.log(data.toUpperCase()); // 文字列であると確認してから使う
}
この例では、まずtypeof data === "string"で「dataが文字列かどうか」を確認しています。文字列であることが分かったあとであれば、toUpperCase()のような「文字列専用のメソッド」を安心して呼び出せます。
プログラミング未経験の方は、「unknown型は、とりあえず受け取るけれど、使う前に必ず中身チェックをするための型」だと思っておくと理解しやすいです。型をはっきりさせながら進めることで、TypeScriptの型安全性を保ちながら、柔軟にデータを扱えるようになります。
3. void型とunknown型の違いを簡単にまとめると?
- void型:関数が何も返さないことを明確に示すための型。
- unknown型:値は存在しているが、その正体がまだ分からない状態を扱うための型。
この2つは名前が似ていますが、役割はまったく異なります。どちらも使い方を理解しておくと、TypeScriptでのコードがとても読みやすくなり、誤った使い方を避けられます。
イメージしやすいように、日常の例に置き換えて考えてみましょう。
void型は、誰かに頼んだ仕事が「結果として何も持ってこない」状態です。たとえば「机を拭いておいて」と依頼したら、作業はしてくれるけれど、何か物を持って返ってくるわけではありません。行動だけが行われ、結果のデータは存在しない——まさに空の封筒のようなものです。
一方でunknown型は、中身が入っているけれど封筒の中が見えない状態です。届いた封筒を開けるまで、それが手紙なのかメモなのか、あるいは写真なのかは分かりません。何かが入っていることは確かですが、開けて確認しないと安全に扱えないという点がポイントです。
この違いを理解しておくことで、「値がない」のか「値はあるが正体不明なのか」という判断がしやすくなり、TypeScriptの型設計がよりクリアになります。
4. unknown型を使うと安全になる理由
JavaScriptでは、どんな型の値でも自由に代入できる反面、意図しない型のまま処理を進めてしまい、思わぬバグにつながることがよくあります。特に、外部サービスから取得したデータやユーザー入力は、必ずしも想定どおりの型とは限りません。
そこで役に立つのがunknown型です。unknown型は「値はあるけれど、正体が分からないもの」を安全に扱うための仕組みで、TypeScriptが“型の確認をしないまま使うのは禁止ですよ”と警告してくれます。
つまり、プログラマーが必ず中身をチェックしないと使えない仕組みになっているため、誤ったメソッドを呼び出してしまう事故を防げます。これがunknown型が安全だと言われる理由です。
例えば、次のように「データが文字列かもしれないし違うかもしれない」という状況で役に立ちます。
let response: unknown = getApiResponse(); // APIの戻り値が不明
if (typeof response === "string") {
console.log("取得した文字列:", response.toUpperCase());
} else {
console.log("文字列ではないデータでした");
}
このように、コードを実行する前に型を確認することで、プログラムの挙動が安定し、思わぬエラーに振り回されるリスクを減らせます。特に初心者のうちは、こうした「安全に扱う手順」を意識することで、より読みやすく信頼性の高いコードを書けるようになります。
5. any型との違いも覚えておこう
ここで似た名前のany型とunknown型の違いも簡単に紹介しておきましょう。
any型は、なんでもありの型で、中身の確認なしで何でもできてしまいます。
でもこれは、TypeScriptの型のチェックを無視してしまうため、バグの元になりやすいです。
一方、unknown型は、「何でも入るけど、使う前にチェックしないといけない」という制限があるので、安全に使うことができます。
let value1: any = "文字列";
console.log(value1.toUpperCase()); // エラーにならないが、バグが起きやすい
let value2: unknown = "文字列";
// console.log(value2.toUpperCase()); ←これはエラーになる
6. void型・unknown型を使うときのポイント
- void型は、主に「関数の戻り値がない」ときだけに使う
- unknown型は、型がはっきりしないデータを安全に扱いたいときに使う
unknownを使う場合は、typeofやinstanceofなどで中身を確認することが必須
まとめ
TypeScript(タイプスクリプト)におけるvoid型とunknown型は、初心者にとって特に混同しやすい型のひとつです。しかし、それぞれの使いどころをしっかりと理解しておけば、コードの可読性と安全性を高める大きな武器になります。
まず、void型は「関数が何も返さない」という明確な目的で使われる型です。これはたとえば、ログを出力するだけの処理や、何らかの副作用だけを持つ処理にぴったり合います。関数の設計意図を明確にすることで、将来的にコードを読む他の開発者にも優しい構造になります。
一方、unknown型は「中身はあるけれど、まだ正体が不明なもの」を扱うときに使います。JavaScriptでは柔軟すぎるがゆえに、予期しない型のデータが流れ込むことが多く、それがバグの原因になるケースも少なくありません。unknown型を使うことで、型を確認してから使用するという安全な流れを強制できるため、より堅牢なアプリケーションを作ることができます。
とくにAPIなど外部からデータを受け取る場合や、ユーザー入力を受け取る場面では、最初はunknownとして保持し、typeofやinstanceofでチェックするスタイルが一般的です。これは、セキュリティ的にも重要な習慣になります。
ここで、それぞれの型の特徴をあらためて比較する簡単な例を紹介します。
サンプル:void型とunknown型の違いを体験しよう
// void型の関数
function logMessage(): void {
console.log("ログを出力しました。");
}
// unknown型の変数と確認
let input: unknown = "テスト文字列";
if (typeof input === "string") {
console.log(input.toUpperCase()); // 安全に使用できる
}
ログを出力しました。
テスト文字列
このコードのように、void型は「値を返さない関数の明示」、unknown型は「型安全な使い方のための型チェック」が肝になります。
また、any型とunknown型の違いも非常に重要です。any型は便利なように見えて、実は型の恩恵をすべて無視してしまう危険な存在です。すぐにはエラーが出ず、気づかないままバグが潜む可能性があります。unknown型は、「使うには型を確認して」という制限があるぶん、プログラマーに良い習慣を促してくれます。
さらに、型を明示することでエディタの補完やコード補正の助けにもなり、開発の効率そのものも向上します。初心者のうちはエラーが多くて戸惑うかもしれませんが、voidやunknownといった型を積極的に使っていくことで、次第に型と仲良くなる感覚が身についていきます。
今回のような基礎的な型をひとつずつ丁寧に学び、少しずつ自分のコードに取り入れていくことで、TypeScriptを用いた堅牢な開発ができるようになります。
生徒
「先生、void型とunknown型って、なんとなく言葉が難しそうでしたけど、今回の説明でかなり分かってきました!」
先生
「よかったですね。void型は何も返さない関数に使うと明確になり、unknown型は安全に値を扱うための工夫として覚えておくと便利ですよ。」
生徒
「たしかに、APIから受け取る値とか、ユーザーの入力とか、型が分からないことって多いですもんね。」
先生
「そのとおり。unknown型でいったん受け取って、あとから型チェックを入れると、安心して扱えるようになります。今回の内容は、これからTypeScriptでアプリを作るときにとても役立ちますよ。」
生徒
「any型よりもunknown型を使うクセをつけるように意識してみます!」
先生
「素晴らしい心がけですね。型の仕組みを理解していくことで、より安心できるコードが書けるようになりますよ。」