• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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