T extends U ? X : Y Conditional Types

Last updated: 2026-10-22

T extends U ? X : Y Conditional Types

Conditional types let types take an exam: T extends U ? X : Y — pick X if the condition holds, Y otherwise. It moves the runtime ternary to the type level, and combined with generics yields return types that adapt to their input.

GroupGenerics
KindSyntax
Strict modeNot required

ℹ️ Info The editor transpiles TypeScript to JavaScript and runs it (no type checking); see each example's Output for type-check results.

📝 Syntax

type Wrapped<T> = T extends string
  ? { kind: "str"; value: T }
  : { kind: "num"; value: number };

type A = Wrapped<string>;  // { kind: "str"; value: string }
type B = Wrapped<number>;  // { kind: "num"; value: number }

// Unions distribute across the check (a distributive conditional)
type ToArray<T> = T extends unknown ? T[] : never;

⚙️ Parameters

T extends UThe condition: if structurally compatible, take the true branch
? X : YThe two branches: full type expressions, may nest further conditionals

Returns:Conditional types are pure type-level computation with no runtime code; the result depends on whether the generic argument satisfies extends.

▶ Example

Edit the code below and click Try it to see the transpiled result:

Output:

{"kind":"str","value":"hi"}
{"kind":"num","value":7}

(Runtime output after transpilation; wrap(true) is a compile error — no overload accepts boolean)

💡 Notes

ℹ️ Info A naked type parameter distributes over unions: ToArray<string | number> is string[] | number[], not (string | number)[] — the distributive conditional, also how Exclude is implemented.
💡 Tip never is the "filter out" signal: type NonNull<T> = T extends null | undefined ? never : T drops null/undefined members after distribution.
⚠️ Note Readability collapses beyond three levels of nesting: prefer mapped types or indexed access where possible, and break deep nesting into intermediate type aliases.
More cases coming soon.

📚 Related tutorials

❓ FAQ

Q Conditional types or overloads?
A One or two simple branches → a single signature with a conditional type; many branches or literal-precision needs → overloads. They mix well (as the example shows).
Q Why does T extends string "hold" for string | number too?
A Distribution is at work: the union is split, checked member by member, then merged. To test the union as a whole, wrap in tuples: [T] extends [string].
Q Can conditional types be used on parameters?
A Yes but carefully: conditionals in parameter positions make caller inference subtle; the common pattern is generic parameters with a conditional return type.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏