// @strict: true type TestObj = { a: string; b: number; }; // Should be never but without an error type Result1 = TestObj[never]; type EmptyObj = {}; // Should be never but without an error type Result2 = EmptyObj[keyof EmptyObj]; declare function genericFn1(obj: T): T[never]; // Should be never const result3 = genericFn1({ c: "ctest", d: "dtest" }); declare function genericFn2( obj: T ): T[never]; // Should be never const result4 = genericFn2({ e: "etest", f: "ftest" }); declare function genericFn3< T extends { [K in keyof T]: T[K] }, U extends keyof T, V extends keyof T >(obj: T, u: U, v: V): T[U & V]; // Should be never const result5 = genericFn3({ g: "gtest", h: "htest" }, "g", "h"); // 'g' & 'h' will reduce to never declare const obj: {a: string, b: number} declare const key: never const result6 = obj[key] // Expanded examples from https://github.com/Microsoft/TypeScript/issues/21988 type RequiredPropNames = { [P in keyof T]-?: undefined extends T[P] ? never : P }[keyof T]; type OptionalPropNames = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T]; type RequiredProps = { [P in RequiredPropNames]: T[P] }; type OptionalProps = { [P in OptionalPropNames]?: T[P] }; type Match = [Exp] extends [Act] ? ([Act] extends [Exp] ? "Match" : "Did not match 2") : "Did not match 1"; type ExpectType = Match extends "Match" ? ({} extends Exp ? Match, Required> : "Match") : "Did not match"; type P3 = { a: string; b: number; c?: boolean }; type P2 = { a: string; c?: boolean }; type P1 = { c?: boolean }; type P0 = {}; type P3Names = RequiredPropNames; // expect 'a' | 'b' type P2Names = RequiredPropNames; // expect 'a' type P1Names = RequiredPropNames; // expect never type P0Names = RequiredPropNames; // expect never declare const p3NameTest: ExpectType<"a" | "b", P3Names>; declare const p2NameTest: ExpectType<"a", P2Names>; declare const p1NameTest: ExpectType; declare const p0NameTest: ExpectType; type P3Props = RequiredProps; // expect { a: string; b: number } type P2Props = RequiredProps; // expect { a: string; } type P1Props = RequiredProps; // expect {} type P0Props = RequiredProps; // expect {} declare const p3Test: ExpectType<{ a: string; b: number }, P3Props>; declare const p2Test: ExpectType<{ a: string }, P2Props>; declare const p1Test: ExpectType<{}, P1Props>; declare const p0Test: ExpectType<{}, P0Props>; type O3 = { a?: string; b?: number; c: boolean }; type O2 = { a?: string; c: boolean }; type O1 = { c: boolean }; type O0 = {}; type O3Names = OptionalPropNames; // expect 'a' | 'b' type O2Names = OptionalPropNames; // expect 'a' type O1Names = OptionalPropNames; // expect never type O0Names = OptionalPropNames; // expect never declare const o3NameTest: ExpectType<"a" | "b", O3Names>; declare const o2NameTest: ExpectType<"a", O2Names>; declare const o1NameTest: ExpectType; declare const o0NameTest: ExpectType; type O3Props = OptionalProps; // expect { a?: string | undefined; b?: number | undefined } type O2Props = OptionalProps; // expect { a?: string | undefined; } type O1Props = OptionalProps; // expect {} type O0Props = OptionalProps; // expect {} declare const o3Test: ExpectType<{ a?: string; b?: number }, O3Props>; declare const o2Test: ExpectType<{ a?: string }, O2Props>; declare const o1Test: ExpectType<{}, O1Props>; declare const o0Test: ExpectType<{}, O0Props>; // Repro from #23005 type Example> = T['a']; type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y" type Res2 = Example<{ a: "x" }>; // "x" type Res3 = Example; // never