関数の境界をまたぐunionの絞り込み
判別可能なunion、Predicateの戻り値、Result形式の型を使い、関数の境界をまたいで安全な絞り込みを維持します
「関数の境界をまたぐunionの絞り込み」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン3/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全3レッスンが含まれています。
導入
目標:タグ付きユニオン、述語の戻り値、検証ヘルパーを使って、関数呼び出しをまたいでも型の絞り込みを維持します。
- 呼び出し側で安全でない
asを使わない - 絞り込み情報をデータとともに渡す
タグ付きユニオンの戻り値
Resultパターンでは、呼び出し側がokをチェックして型を絞り込みます。キャストが不要で、制御フローも明確です。
type Ok<T> = { ok: true; value: T }
type Err = { ok: false; error: string }
type Result<T> = Ok<T> | Err
function parseIntSafe(s: string): Result<number> {
const n = Number(s)
return Number.isFinite(n) ? { ok: true, value: n } : { ok: false, error: "NaN" }
}
function useIt(s: string) {
const r = parseIntSafe(s)
if (r.ok) {
// r is Ok<number>
return r.value * 2
}
// r is Err
return `bad: ${r.error}`
}述語の戻り値
述語の戻り値(x is T)にチェックを集約し、呼び出し側で型の絞り込みを維持します。
type User = { id: number; name: string }
type MaybeUser = User | null
function hasUser(x: MaybeUser): x is User {
return x !== null
}
function greet(x: MaybeUser) {
if (hasUser(x)) {
// x narrowed to User
return `Hello ${x.name}`
}
return "Anonymous"
}絞り込み情報の受け渡し
ガード(例:isCircle)で型を絞り込んでから値を渡すと、下流の関数でもより狭い型として認識されます。
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number }
function isCircle(s: Shape): s is Extract<Shape, { kind: "circle" }> {
return s.kind === "circle"
}
function area(s: Shape) {
if (isCircle(s)) {
// s is circle here
return Math.PI * s.radius * s.radius
}
return s.size * s.size
}境界で検証する
境界で検証してValid/Invalidを返します。呼び出し側はタグで型を絞り込み、完全に型付けされたデータを取得できます。
type Payload = { email: string; retries?: number }
type Valid = { ok: true; data: Required<Payload> }
type Invalid = { ok: false; issues: string[] }
type Validation = Valid | Invalid
function validate(p: unknown): Validation {
const issues: string[] = []
if (typeof p !== "object" || p === null) return { ok: false, issues: ["not an object"] }
const x = p as any
if (typeof x.email !== "string") issues.push("email:string")
if (x.retries !== undefined && typeof x.retries !== "number") issues.push("retries:number")
if (issues.length) return { ok: false, issues }
return { ok: true, data: { email: x.email, retries: x.retries ?? 0 } }
}
function handle(p: unknown) {
const v = validate(p)
if (!v.ok) return `bad: ${v.issues.join(",")}`
// v.data is fully typed here
return `send to ${v.data.email} (${v.data.retries})`
}ヒント
ベストプラクティス:
- 小さく安定したタグ(ok、kind)を優先する
- チェックを述語ヘルパーに集約する
- 呼び出し側で網羅的なswitchを使う
anyと安全でないキャストを避ける
境界を越えた型の絞り込み
クイックチェック:関数の境界を越えて型の絞り込みを最も適切に維持するパターンはどれでしょうか。
まとめ
まとめ:絞り込み情報をデータ(Result)として渡し、境界で検証し、安全でないキャストを避けます。呼び出し側では単純なタグチェックによって型を絞り込めます。
よくある質問
「関数の境界をまたぐunionの絞り込み」レッスンは無料ですか?
はい。「関数の境界をまたぐunionの絞り込み」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全3レッスンが含まれています。
「関数の境界をまたぐunionの絞り込み」で何を学びますか?
判別可能なunion、Predicateの戻り値、Result形式の型を使い、関数の境界をまたいで安全な絞り込みを維持します ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/3です。
「関数の境界をまたぐunionの絞り込み」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 網羅的なswitchとneverチェック
- Predicate関数とsatisfies演算子
- 関数の境界をまたぐunionの絞り込み