Below is a five-line “playground-size” demo that lets you watch the conditional type stay in its unevaluated form inside a generic function and collapse as soon as you call the function with a concrete argument.
// 1 ─ a tiny conditional type
type Kind<T> = T extends string ? "str" : "other";
// 2 ─ generic function: the test type receives a **bare** type parameter
function lazy<T>(value: T) {
  type Inside = Kind<T>;          // 3: Inside is still  Kind<T>
  return null as unknown as Inside;
}
// 4 ─ call sites supply concrete types, so the compiler finally reduces it
const a = lazy("hello");   // a: "str"
const b = lazy(123);       // b: "other"- 
Line 3 (inside
lazy)Tis a bare type parameter, so the compiler postpones the testT extends string ? … : …. Hover in an editor and you’ll seeInsidereported literally asKind<T>—the conditional hasn’t run yet. - 
Lines 4 – 5 (outside
lazy) Each call substitutes a concrete type (stringornumber) forT. Now the condition can be decided, soKind<string>reduces to"str"andKind<number>to"other". 
That postponement is exactly what TypeScript’s documentation refers to as “deferred” or “lazy” evaluation of conditional types involving bare type parameters.