is possibly 'undefined' の原因と直し方
interfaceで?を付けたオプショナルプロパティは、値が入っていない(undefined)可能性を型として保持します。narrowing(存在確認)をせずにメソッドやプロパティへアクセスすると、このエラーになります。
エラーメッセージの読み方
main.ts(5,10): error TS18048: 'p.bio' is possibly 'undefined'.
main.ts- ファイル名
5- 行番号
10- 列番号 — この位置でtscが検査に失敗しました
TS18048- エラーコード — 検索するとTypeScriptの解説が見つかります
'p.bio' is possibly 'undefined'.- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 interface Profile { 2 bio?: string; 3 } 4 function shout(p: Profile): string { 5 return p.bio .toUpperCase(); ^ 6 } 7 console.log(shout({ bio: "hi" }));
main.ts(5,10): error TS18048: 'p.bio' is possibly 'undefined'.
bioはオプショナルプロパティなのでundefinedかもしれません。narrowingせずにtoUpperCase()を呼ぶとエラーになります。
直し方: bio を bio! にします。
広告
広告スロット(未設定)
パターン2
1 interface Cart { 2 coupon?: string; 3 } 4 function applyCoupon(c: Cart): number { 5 return c.coupon .length; ^ 6 } 7 console.log(applyCoupon({ coupon: "SAVE10" }));
main.ts(5,10): error TS18048: 'c.coupon' is possibly 'undefined'.
couponもオプショナルなのでundefinedの可能性があります。lengthへアクセスする前に確認が必要です。
直し方: coupon を coupon! にします。
パターン3
1 interface Options { 2 timeout?: number; 3 } 4 function describe(o: Options): number { 5 return o.timeout + 1; ^ 6 } 7 console.log(describe({ timeout: 9 }));
main.ts(5,10): error TS18048: 'o.timeout' is possibly 'undefined'.
timeoutはオプショナルなnumberです。undefinedかもしれない値に対して+演算はできません。
直し方: timeout を timeout! にします。
よくある誤解
「オプショナルプロパティも、実際に値を渡していれば安全なはず」という考えは、TypeScriptの型チェックには通用しません。tscは呼び出し元の実際の値ではなく、型として「undefinedかもしれない」という可能性だけを見て機械的に判定します。
まとめ
is possibly 'undefined'は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。