A conditional type chooses one type when a generic value matches a shape and another type otherwise.

conditional type `T extends U ? A : B` selects `A` when `T` fits `U`; otherwise it selects `B`.

Conditional Label Type

useNumber
label_type.ts
Replay: real traced execution (multi-file project)
type ValueLabel<T> = T extends number ? "number" : "text";

function labelValue<T extends number | string>(value: T): ValueLabel<T> {
    return (typeof value === "number" ? "number" : "text") as ValueLabel<T>;
}

const useNumber: boolean = true;
const value: number | string = useNumber ? 12 : "trace";
const label: "number" | "text" = labelValue(value);

console.log(`${label}:${value}`);
type ValueLabel<T> = T extends number ? "number" : "text";

function labelValue<T extends number | string>(value: T): ValueLabel<T> {
    return (typeof value === "number" ? "number" : "text") as ValueLabel<T>;
}

const useNumber: boolean = false;
const value: number | string = useNumber ? 12 : "trace";
const label: "number" | "text" = labelValue(value);

console.log(`${label}:${value}`);
  1. useNumber ← true, value ← 12

    4    return (typeof value === "number" ? "number" : "text") as ValueLabel<T>;5}67const useNumber→ true: boolean = true;  //@useNumber=false8const value→ 12: number | string = useNumbertrue ? 12 : "trace";9const label: "number" | "text" = labelValue(value12);
  2. function labelValue<T extends number | string>(value: T): ValueLabel<T…

    1type ValueLabel<T> = T extends number ? "number" : "text";23function labelValue<T extends number | string>(value12: T): ValueLabel<T> {4    return (typeof value === "number" ? "number" : "text") as ValueLabel<T>;5}
  3. label ← number

    7const useNumber: boolean = true;  //@useNumber=false8const value: number | string = useNumber ? 12 : "trace";9const label→ number: "number" | "text" = labelValue(value12);1011console.log(`${labelnumber}:${value12}`);
    outputnumber:12
  1. useNumber ← false, value ← trace

    4    return (typeof value === "number" ? "number" : "text") as ValueLabel<T>;5}67const useNumber→ false: boolean = false;8const value→ trace: number | string = useNumberfalse ? 12 : "trace";9const label: "number" | "text" = labelValue(valuetrace);
  2. function labelValue<T extends number | string>(value: T): ValueLabel<T…

    1type ValueLabel<T> = T extends number ? "number" : "text";23function labelValue<T extends number | string>(valuetrace: T): ValueLabel<T> {4    return (typeof value === "number" ? "number" : "text") as ValueLabel<T>;5}
  3. label ← text

    7const useNumber: boolean = false;8const value: number | string = useNumber ? 12 : "trace";9const label→ text: "number" | "text" = labelValue(valuetrace);1011console.log(`${labeltext}:${valuetrace}`);
    outputtext:trace