Уточнение объединений на границах функций
Сохраняйте безопасное сужение типов на границах функций с помощью дискриминированных объединений, возвращаемых предикатов и типов в стиле Result.
«Уточнение объединений на границах функций» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 3 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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
}Проверка на границе
Проверяйте данные на границе и возвращайте состояние действительно/недействительно; вызывающая сторона сужает тип по метке и получает полностью типизированные данные.
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), проверяйте данные на границах и избегайте небезопасных приведений типов; вызывающая сторона сужает тип простыми проверками меток.
Часто задаваемые вопросы
Урок «Уточнение объединений на границах функций» бесплатный?
Да — полный текст урока «Уточнение объединений на границах функций» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 3 уроков всего.
Чему я научусь в уроке «Уточнение объединений на границах функций»?
Сохраняйте безопасное сужение типов на границах функций с помощью дискриминированных объединений, возвращаемых предикатов и типов в стиле Result. Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 3.
Сколько времени занимает урок «Уточнение объединений на границах функций»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Полные switch и проверки с never
- Функции-предикаты и оператор satisfies
- Уточнение объединений на границах функций