Skip to content

Instantly share code, notes, and snippets.

@BrandonStudio
Last active May 8, 2025 07:08
Show Gist options
  • Save BrandonStudio/ad611d95d8b4db8605ae0c4a6b25f26e to your computer and use it in GitHub Desktop.
Save BrandonStudio/ad611d95d8b4db8605ae0c4a6b25f26e to your computer and use it in GitHub Desktop.
Typescript typing issue with `extends` keyword
type A = {
s: true;
i: {};
};
type B = {
s: true;
j: {};
};
type C = {
s: false;
i: {};
};
type D = {
s: false;
j: {};
};
type AC = A | C;
type BD = B | D;
type Conditional<T1, T2, B extends true | false> = B extends true ? T1 : T2;
function func1<
Bool extends true | false,
ABCD extends AC | BD,
AC_BD extends Bool extends true ? AC : BD,
>(b: Bool) {
type X = Extract<ABCD, { s: true }>;
// ABCD extends { s: true } ? ABCD : never
// Expected: A | B
type Y = Extract<AC_BD, { s: true }>;
// AC_BD extends { s: true } ? AC_BD : never
// Expected: Conditional<A, B, Bool>
function foo1(): ABCD {
return {} as ABCD;
}
function foo2(): AC_BD {
return {} as AC_BD;
}
const r1 = foo1();
if (r1.s) {
const r1_ = r1; // ABCD. Expected: A | B
} else {
const r1_ = r1; // ABCD. Expected: C | D
}
const r2 = foo2();
if (r2.s) {
const r2_ = r2; // AC_BD. Expected: Conditional<A, B, Bool>
} else {
const r2_ = r2; // AC_BD. Expected: Conditional<C, D, Bool>
}
}
function func2<Bool extends true | false>(b: Bool) {
type X = Extract<AC | BD, { s: true }>; // A | B. ✓
type Y = Extract<Conditional<AC, BD, Bool>, { s: true }>;
// Conditional<AC, BD, Bool> extends { s: true; } ? { s: true; } & Conditional<AC, BD, Bool> : never
// Expected: Conditional<A, B, Bool>
function foo1(): AC | BD {
return {} as AC | BD;
}
function foo2(): Conditional<AC, BD, Bool> {
return {} as Conditional<AC, BD, Bool>;
}
const r1 = foo1();
if (r1.s) {
const r1_ = r1; // A | B. ✓
} else {
const r1_ = r1; // C | D. ✓
}
const r2 = foo2();
if (r2.s) {
const r2_ = r2; // Conditional<AC, BD, Bool>. Expected: Conditional<A, B, Bool>
} else {
const r2_ = r2; // Conditional<AC, BD, Bool>. Expected: Conditional<C, D, Bool>
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment