never型と不可能な状態
neverを使って、到達不能なコードや不可能な値をモデル化します。
「never型と不可能な状態」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。
never 型
never は空の型であり、決して発生しない値を表します。never 自体を除き、どの値も never には代入できません。発生してはならない状況を示すために使われます。
// You cannot create a value of type never
function crash(): never {
throw new Error('boom');
}
try { crash(); } catch (e) { console.log('caught'); }決して戻らない関数
常に throw する関数は正常に戻ることがないため、戻り値の型は never になります。これにより、呼び出し元とコンパイラーに、ここで実行が停止することを伝えます。
function fail(message: string): never {
throw new Error(message);
}
try { fail('invalid'); } catch (e) { console.log('handled'); }無限ループは never を返す
無限ループを持つ関数も決して戻らないため、同様に never として型付けされます。コンパイラーは、その先に制御フローが続かないことを認識します。
function listen(): never {
while (true) {
// forever
break; // (break added so the demo terminates)
}
throw new Error('stopped');
}
console.log('listen has return type never');never と void の違い
never と void を混同しないでください。void 型の関数は戻ります(有用な値を返さないだけです)。never 型の関数はまったく戻りません。例外を投げるか、永遠にループします。
function logIt(): void {
console.log('done'); // returns normally
}
function abort(): never {
throw new Error('stop'); // never returns
}
logIt();
try { abort(); } catch (e) { console.log('ok'); }網羅性チェックで never を使う
never の最も実用的な用途は、網羅性チェックです。switch の default で、変数を never に代入します。すべてのケースが処理されていれば、その変数はすでに never なのでコンパイルできます。
type Shape = 'circle' | 'square';
function area(s: Shape): string {
switch (s) {
case 'circle': return 'pi r^2';
case 'square': return 'a^2';
default:
const _check: never = s; // ok: all handled
return _check;
}
}
console.log(area('square'));処理漏れの検出
誰かが新しいユニオンメンバーを追加したのにケースの追加を忘れると、残った値はもはや never ではないため、代入のコンパイルに失敗します。never チェックによって、気付かれない処理漏れが明確なエラーになります。
type Shape = 'circle' | 'square' | 'triangle';
// If 'triangle' case is missing, assigning s to never
// would error: 'triangle' is not assignable to never.
console.log('Add a case for every member');不可能なユニオン分岐で never を使う
型の絞り込みによってすべての可能性が取り除かれると、残りの型は never になります。コンパイラーはその分岐に到達できないことを認識するため、ロジックの誤りを発見できる場合があります。
function check(x: string | number): void {
if (typeof x === 'string') {
console.log('string');
} else if (typeof x === 'number') {
console.log('number');
} else {
// x is never here
console.log('unreachable');
}
}
check('hi');ボトム型としての never
never はボトム型です。存在しない値はどの型にも矛盾なく適合するとみなせるため、他のすべての型に代入できます。これが、throw を任意の式の位置に置ける理由です。
function getOrThrow(v: string | null): string {
return v ?? fail();
}
function fail(): never {
throw new Error('missing');
}
console.log(getOrThrow('value'));ユニオンを never に絞り込む
条件付き型やマップ型では、never は「これを削除する」という働きをします。never とのユニオンは何も変えません。T | never は単に T です。そのため、フィルタリングに自然に利用できます。
type Keep<T> = T extends string ? T : never;
type R = Keep<'a' | 1 | 'b'>; // 'a' | 'b'
const x: R = 'a';
console.log(x);不可能な状態をモデル化する
オブジェクトの形状に never を使うと、許可されない組み合わせを表現できないようにできます。ここでは、型によって「読み込み中」の状態がデータを同時に持てないようにしています。
type State =
| { status: 'loading'; data?: never }
| { status: 'ready'; data: number };
const s: State = { status: 'ready', data: 7 };
console.log(s);never によるリファクタリングの安全性向上
never による網羅性チェックは、ケースが不足すると失敗するため、リファクタリングを安全にします。ユニオンを拡張すると、更新が必要なすべての箇所をコンパイラーが示してくれます。
type Cmd = 'start' | 'stop';
function run(c: Cmd): string {
if (c === 'start') return 'starting';
if (c === 'stop') return 'stopping';
const _x: never = c;
return _x;
}
console.log(run('start'));理解度チェック
never 型の理解度を確認しましょう。
振り返り: never
neverについて、次のことを学びました。
- 空の型であり、
never型の値は存在しません。 - 例外をスローするか、無限ループする関数の戻り値の型です。
- switch の default 節における網羅性チェックを可能にします。
- 到達不能な絞り込み分岐に現れ、型の論理ではユニオン型をフィルタリングします。
次はvoidを取り上げ、どのように異なるのかを見ていきます。
function assertNever(x: never): never {
throw new Error('Unexpected: ' + String(x));
}
console.log('assertNever guards exhaustiveness');AI チューターと学ぶ TypeScript — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 101
- レッスン
- 352
よくある質問
「never型と不可能な状態」レッスンは無料ですか?
はい。「never型と不可能な状態」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。
「never型と不可能な状態」で何を学びますか?
neverを使って、到達不能なコードや不可能な値をモデル化します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「never型と不可能な状態」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- unknownとanyを理解する
- never型と不可能な状態
- 関数におけるvoid型
- unknownの型安全な扱い