1/* 2* Copyright (c) Microsoft Corporation. All rights reserved. 3* Copyright (c) 2023 Huawei Device Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15* 16* This file has been modified by Huawei to verify type inference by adding verification statements. 17*/ 18 19// === tests/cases/compiler/indexingTypesWithNever.ts === 20declare function AssertType(value:any, type:string):void; 21type TestObj = { 22 a: string; 23 b: number; 24}; 25 26// Should be never but without an error 27type Result1 = TestObj[never]; 28 29type EmptyObj = {}; 30 31// Should be never but without an error 32type Result2 = EmptyObj[keyof EmptyObj]; 33 34declare function genericFn1<T>(obj: T): T[never]; 35 36// Should be never 37const result3 = genericFn1({ c: "ctest", d: "dtest" }); 38AssertType(result3, "never"); 39AssertType(genericFn1({ c: "ctest", d: "dtest" }), "never"); 40AssertType(genericFn1, "<T>(T) => T[never]"); 41AssertType({ c: "ctest", d: "dtest" }, "{ c: string; d: string; }"); 42AssertType(c, "string"); 43AssertType("ctest", "string"); 44AssertType(d, "string"); 45AssertType("dtest", "string"); 46 47declare function genericFn2<T extends { [ind: string]: string }>( 48 obj: T 49): T[never]; 50 51// Should be never 52const result4 = genericFn2({ e: "etest", f: "ftest" }); 53AssertType(result4, "never"); 54AssertType(genericFn2({ e: "etest", f: "ftest" }), "never"); 55AssertType(genericFn2, "<T extends { [string]: string; }>(T) => T[never]"); 56AssertType({ e: "etest", f: "ftest" }, "{ e: string; f: string; }"); 57AssertType(e, "string"); 58AssertType("etest", "string"); 59AssertType(f, "string"); 60AssertType("ftest", "string"); 61 62declare function genericFn3< 63 T extends { [K in keyof T]: T[K] }, 64 U extends keyof T, 65 V extends keyof T 66>(obj: T, u: U, v: V): T[U & V]; 67 68// Should be never 69const result5 = genericFn3({ g: "gtest", h: "htest" }, "g", "h"); // 'g' & 'h' will reduce to never 70AssertType(result5, "never"); 71AssertType(genericFn3({ g: "gtest", h: "htest" }, "g", "h"), "never"); 72AssertType(genericFn3, "<T extends { [K in keyof T]: T[K]; }, U extends keyof T, V extends keyof T>(T, U, V) => T[U & V]"); 73AssertType({ g: "gtest", h: "htest" }, "{ g: string; h: string; }"); 74AssertType(g, "string"); 75AssertType("gtest", "string"); 76AssertType(h, "string"); 77AssertType("htest", "string"); 78AssertType("g", "string"); 79AssertType("h", "string"); 80 81 82declare const obj: {a: string, b: number 83AssertType(obj, "{ a: string; b: number; }"); 84 85AssertType(a, "string"); 86 87AssertType(b, "number"); 88} 89 90declare const key: never 91AssertType(key, "never"); 92 93const result6 = obj[key] 94AssertType(result6, "never"); 95AssertType(obj[key], "never"); 96AssertType(obj, "{ a: string; b: number; }"); 97AssertType(key, "never"); 98 99// Expanded examples from https://github.com/Microsoft/TypeScript/issues/21988 100type RequiredPropNames<T> = { 101 [P in keyof T]-?: undefined extends T[P] ? never : P 102}[keyof T]; 103 104type OptionalPropNames<T> = { 105 [P in keyof T]-?: undefined extends T[P] ? P : never 106}[keyof T]; 107 108type RequiredProps<T> = { [P in RequiredPropNames<T>]: T[P] }; 109type OptionalProps<T> = { [P in OptionalPropNames<T>]?: T[P] }; 110 111type Match<Exp, Act> = [Exp] extends [Act] 112 ? ([Act] extends [Exp] ? "Match" : "Did not match 2") 113 : "Did not match 1"; 114 115type ExpectType<Exp, Act> = Match<Exp, Act> extends "Match" 116 ? ({} extends Exp ? Match<Required<Exp>, Required<Act>> : "Match") 117 : "Did not match"; 118 119type P3 = { a: string; b: number; c?: boolean }; 120type P2 = { a: string; c?: boolean }; 121type P1 = { c?: boolean }; 122type P0 = {}; 123 124type P3Names = RequiredPropNames<P3>; // expect 'a' | 'b' 125type P2Names = RequiredPropNames<P2>; // expect 'a' 126type P1Names = RequiredPropNames<P1>; // expect never 127type P0Names = RequiredPropNames<P0>; // expect never 128 129declare const p3NameTest: ExpectType<"a" | "b", P3Names>; 130AssertType(p3NameTest, "string"); 131 132declare const p2NameTest: ExpectType<"a", P2Names>; 133AssertType(p2NameTest, "string"); 134 135declare const p1NameTest: ExpectType<never, P1Names>; 136AssertType(p1NameTest, "string"); 137 138declare const p0NameTest: ExpectType<never, P0Names>; 139AssertType(p0NameTest, "string"); 140 141type P3Props = RequiredProps<P3>; // expect { a: string; b: number } 142type P2Props = RequiredProps<P2>; // expect { a: string; } 143type P1Props = RequiredProps<P1>; // expect {} 144type P0Props = RequiredProps<P0>; // expect {} 145 146declare const p3Test: ExpectType<{ a: string; b: number }, P3Props>; 147AssertType(p3Test, "string"); 148AssertType(a, "string"); 149AssertType(b, "number"); 150 151declare const p2Test: ExpectType<{ a: string }, P2Props>; 152AssertType(p2Test, "string"); 153AssertType(a, "string"); 154 155declare const p1Test: ExpectType<{}, P1Props>; 156AssertType(p1Test, "string"); 157 158declare const p0Test: ExpectType<{}, P0Props>; 159AssertType(p0Test, "string"); 160 161type O3 = { a?: string; b?: number; c: boolean }; 162type O2 = { a?: string; c: boolean }; 163type O1 = { c: boolean }; 164type O0 = {}; 165 166type O3Names = OptionalPropNames<O3>; // expect 'a' | 'b' 167type O2Names = OptionalPropNames<O2>; // expect 'a' 168type O1Names = OptionalPropNames<O1>; // expect never 169type O0Names = OptionalPropNames<O0>; // expect never 170 171declare const o3NameTest: ExpectType<"a" | "b", O3Names>; 172AssertType(o3NameTest, "string"); 173 174declare const o2NameTest: ExpectType<"a", O2Names>; 175AssertType(o2NameTest, "string"); 176 177declare const o1NameTest: ExpectType<never, O1Names>; 178AssertType(o1NameTest, "string"); 179 180declare const o0NameTest: ExpectType<never, O0Names>; 181AssertType(o0NameTest, "string"); 182 183type O3Props = OptionalProps<O3>; // expect { a?: string | undefined; b?: number | undefined } 184type O2Props = OptionalProps<O2>; // expect { a?: string | undefined; } 185type O1Props = OptionalProps<O1>; // expect {} 186type O0Props = OptionalProps<O0>; // expect {} 187 188declare const o3Test: ExpectType<{ a?: string; b?: number }, O3Props>; 189AssertType(o3Test, "string"); 190AssertType(a, "union"); 191AssertType(b, "union"); 192 193declare const o2Test: ExpectType<{ a?: string }, O2Props>; 194AssertType(o2Test, "string"); 195AssertType(a, "union"); 196 197declare const o1Test: ExpectType<{}, O1Props>; 198AssertType(o1Test, "string"); 199 200declare const o0Test: ExpectType<{}, O0Props>; 201AssertType(o0Test, "string"); 202 203// Repro from #23005 204 205type Example<T extends Record<'a', string>> = T['a']; 206 207type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y" 208type Res2 = Example<{ a: "x" }>; // "x" 209type Res3 = Example<never>; // never 210 211 212