Skip to content

Commit 43c24bb

Browse files
committed
add tests, fix comment
1 parent 0308dde commit 43c24bb

File tree

5 files changed

+273
-44
lines changed

5 files changed

+273
-44
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24887,10 +24887,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2488724887

2488824888
// This like getBaseTypeOfLiteralType, but instead treats enum literals as strings/numbers instead
2488924889
// of returning their enum base type (which depends on the types of other literals in the enum).
24890-
// use to determine if a parameter may be undefined or null (or is unknown/unconstrained)
24891-
// function getUnknownIfMaybeUnknown(type: Type) {
24892-
// return (strictNullChecks && type.flags & TypeFlags.Instantiable) ? getBaseConstraintOfType(type) ?? unknownUnionType : type;
24893-
// }
24890+
// It also checks if the type used in the comparison may be undefined or null (or is unknown/unconstrained)
2489424891
function getBaseTypeForComparison(type: Type): Type {
2489524892
return type.flags & TypeFlags.Instantiable && strictNullChecks ? getBaseConstraintOfType(type) ?? unknownUnionType :
2489624893
type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? stringType :

tests/baselines/reference/unconstrainedTypeComparison.errors.txt

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@ unconstrainedTypeComparison.ts(38,12): error TS18049: 'x' is possibly 'null' or
2020
unconstrainedTypeComparison.ts(38,16): error TS18049: 'y' is possibly 'null' or 'undefined'.
2121
unconstrainedTypeComparison.ts(42,12): error TS18049: 'x' is possibly 'null' or 'undefined'.
2222
unconstrainedTypeComparison.ts(42,16): error TS18049: 'y' is possibly 'null' or 'undefined'.
23-
unconstrainedTypeComparison.ts(46,12): error TS18049: 'x' is possibly 'null' or 'undefined'.
24-
unconstrainedTypeComparison.ts(46,16): error TS18049: 'y' is possibly 'null' or 'undefined'.
25-
unconstrainedTypeComparison.ts(61,12): error TS18047: 'a' is possibly 'null'.
26-
unconstrainedTypeComparison.ts(61,16): error TS18048: 'b' is possibly 'undefined'.
23+
unconstrainedTypeComparison.ts(49,12): error TS18047: 'x' is possibly 'null'.
24+
unconstrainedTypeComparison.ts(49,16): error TS18049: 'y' is possibly 'null' or 'undefined'.
25+
unconstrainedTypeComparison.ts(56,12): error TS18047: 'x' is possibly 'null'.
26+
unconstrainedTypeComparison.ts(56,16): error TS18049: 'y' is possibly 'null' or 'undefined'.
27+
unconstrainedTypeComparison.ts(60,12): error TS18049: 'x' is possibly 'null' or 'undefined'.
28+
unconstrainedTypeComparison.ts(60,16): error TS18049: 'y' is possibly 'null' or 'undefined'.
29+
unconstrainedTypeComparison.ts(74,12): error TS18047: 'x' is possibly 'null'.
30+
unconstrainedTypeComparison.ts(74,16): error TS18048: 'y' is possibly 'undefined'.
31+
unconstrainedTypeComparison.ts(85,12): error TS18047: 'a' is possibly 'null'.
32+
unconstrainedTypeComparison.ts(85,16): error TS18048: 'b' is possibly 'undefined'.
2733

2834

29-
==== unconstrainedTypeComparison.ts (26 errors) ====
35+
==== unconstrainedTypeComparison.ts (32 errors) ====
3036
function f1<T>(a: T, b: T): boolean {
3137
return a > b;
3238
~
@@ -115,16 +121,52 @@ unconstrainedTypeComparison.ts(61,16): error TS18048: 'b' is possibly 'undefined
115121
!!! error TS18049: 'y' is possibly 'null' or 'undefined'.
116122
}
117123

118-
function f12<T, U>(x: T & U, y: T & U) {
124+
function f12<T, U extends T>(x: T | number, y: U | number) {
125+
if (x === undefined) {
126+
return false;
127+
}
128+
return x < y;
129+
~
130+
!!! error TS18047: 'x' is possibly 'null'.
131+
~
132+
!!! error TS18049: 'y' is possibly 'null' or 'undefined'.
133+
}
134+
135+
function f13<T, U extends T | number>(x: U, y: U) {
136+
if (x === undefined) {
137+
return false;
138+
}
139+
return x < y;
140+
~
141+
!!! error TS18047: 'x' is possibly 'null'.
142+
~
143+
!!! error TS18049: 'y' is possibly 'null' or 'undefined'.
144+
}
145+
146+
function f14<T, U>(x: T & U, y: T & U) {
119147
return x < y;
120148
~
121149
!!! error TS18049: 'x' is possibly 'null' or 'undefined'.
122150
~
123151
!!! error TS18049: 'y' is possibly 'null' or 'undefined'.
124152
}
125153

126-
function f13<T, U extends T>(x: T & number, y: U & number) {
154+
function f15<T, U extends T>(x: T & number, y: U & number) {
155+
return x < y;
156+
}
157+
158+
function f16<T, U extends T>(x: T & U, y: U) {
159+
if (x === undefined) {
160+
return false;
161+
}
162+
if (y === null) {
163+
return false;
164+
}
127165
return x < y;
166+
~
167+
!!! error TS18047: 'x' is possibly 'null'.
168+
~
169+
!!! error TS18048: 'y' is possibly 'undefined'.
128170
}
129171

130172

tests/baselines/reference/unconstrainedTypeComparison.symbols

Lines changed: 96 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -161,58 +161,127 @@ function f11<T, U extends T>(x: T | number, y: U | number) {
161161
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 40, 43))
162162
}
163163

164-
function f12<T, U>(x: T & U, y: T & U) {
164+
function f12<T, U extends T>(x: T | number, y: U | number) {
165165
>f12 : Symbol(f12, Decl(unconstrainedTypeComparison.ts, 42, 1))
166166
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 44, 13))
167167
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 44, 15))
168-
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 19))
169168
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 44, 13))
170-
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 44, 15))
171-
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 44, 28))
169+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 29))
172170
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 44, 13))
171+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 44, 43))
173172
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 44, 15))
174173

174+
if (x === undefined) {
175+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 29))
176+
>undefined : Symbol(undefined)
177+
178+
return false;
179+
}
180+
return x < y;
181+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 29))
182+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 44, 43))
183+
}
184+
185+
function f13<T, U extends T | number>(x: U, y: U) {
186+
>f13 : Symbol(f13, Decl(unconstrainedTypeComparison.ts, 49, 1))
187+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 51, 13))
188+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 51, 15))
189+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 51, 13))
190+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 51, 38))
191+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 51, 15))
192+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 51, 43))
193+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 51, 15))
194+
195+
if (x === undefined) {
196+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 51, 38))
197+
>undefined : Symbol(undefined)
198+
199+
return false;
200+
}
201+
return x < y;
202+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 51, 38))
203+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 51, 43))
204+
}
205+
206+
function f14<T, U>(x: T & U, y: T & U) {
207+
>f14 : Symbol(f14, Decl(unconstrainedTypeComparison.ts, 56, 1))
208+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 58, 13))
209+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 58, 15))
210+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 58, 19))
211+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 58, 13))
212+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 58, 15))
213+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 58, 28))
214+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 58, 13))
215+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 58, 15))
216+
217+
return x < y;
218+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 58, 19))
219+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 58, 28))
220+
}
221+
222+
function f15<T, U extends T>(x: T & number, y: U & number) {
223+
>f15 : Symbol(f15, Decl(unconstrainedTypeComparison.ts, 60, 1))
224+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 62, 13))
225+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 62, 15))
226+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 62, 13))
227+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 62, 29))
228+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 62, 13))
229+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 62, 43))
230+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 62, 15))
231+
175232
return x < y;
176-
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 19))
177-
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 44, 28))
233+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 62, 29))
234+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 62, 43))
178235
}
179236

180-
function f13<T, U extends T>(x: T & number, y: U & number) {
181-
>f13 : Symbol(f13, Decl(unconstrainedTypeComparison.ts, 46, 1))
182-
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 48, 13))
183-
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 48, 15))
184-
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 48, 13))
185-
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 48, 29))
186-
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 48, 13))
187-
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 48, 43))
188-
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 48, 15))
237+
function f16<T, U extends T>(x: T & U, y: U) {
238+
>f16 : Symbol(f16, Decl(unconstrainedTypeComparison.ts, 64, 1))
239+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 66, 13))
240+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 66, 15))
241+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 66, 13))
242+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 66, 29))
243+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 66, 13))
244+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 66, 15))
245+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 66, 38))
246+
>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 66, 15))
189247

248+
if (x === undefined) {
249+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 66, 29))
250+
>undefined : Symbol(undefined)
251+
252+
return false;
253+
}
254+
if (y === null) {
255+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 66, 38))
256+
257+
return false;
258+
}
190259
return x < y;
191-
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 48, 29))
192-
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 48, 43))
260+
>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 66, 29))
261+
>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 66, 38))
193262
}
194263

195264

196265
function compare<T>(a: T, b: T): boolean {
197-
>compare : Symbol(compare, Decl(unconstrainedTypeComparison.ts, 50, 1))
198-
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 53, 17))
199-
>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 53, 20))
200-
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 53, 17))
201-
>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 53, 25))
202-
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 53, 17))
266+
>compare : Symbol(compare, Decl(unconstrainedTypeComparison.ts, 74, 1))
267+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 77, 17))
268+
>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 77, 20))
269+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 77, 17))
270+
>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 77, 25))
271+
>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 77, 17))
203272

204273
if (a === undefined) {
205-
>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 53, 20))
274+
>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 77, 20))
206275
>undefined : Symbol(undefined)
207276

208277
return false;
209278
}
210279
if (b === null) {
211-
>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 53, 25))
280+
>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 77, 25))
212281

213282
return false;
214283
}
215284
return a > b;
216-
>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 53, 20))
217-
>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 53, 25))
285+
>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 77, 20))
286+
>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 77, 25))
218287
}

tests/baselines/reference/unconstrainedTypeComparison.types

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,66 @@ function f11<T, U extends T>(x: T | number, y: U | number) {
188188
> : ^^^^^^^^^^
189189
}
190190

191-
function f12<T, U>(x: T & U, y: T & U) {
192-
>f12 : <T, U>(x: T & U, y: T & U) => boolean
191+
function f12<T, U extends T>(x: T | number, y: U | number) {
192+
>f12 : <T, U extends T>(x: T | number, y: U | number) => boolean
193+
> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^
194+
>x : number | T
195+
> : ^^^^^^^^^^
196+
>y : number | U
197+
> : ^^^^^^^^^^
198+
199+
if (x === undefined) {
200+
>x === undefined : boolean
201+
> : ^^^^^^^
202+
>x : number | T
203+
> : ^^^^^^^^^^
204+
>undefined : undefined
205+
> : ^^^^^^^^^
206+
207+
return false;
208+
>false : false
209+
> : ^^^^^
210+
}
211+
return x < y;
212+
>x < y : boolean
213+
> : ^^^^^^^
214+
>x : number | (T & ({} | null))
215+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^
216+
>y : number | U
217+
> : ^^^^^^^^^^
218+
}
219+
220+
function f13<T, U extends T | number>(x: U, y: U) {
221+
>f13 : <T, U extends T | number>(x: U, y: U) => boolean
222+
> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^
223+
>x : U
224+
> : ^
225+
>y : U
226+
> : ^
227+
228+
if (x === undefined) {
229+
>x === undefined : boolean
230+
> : ^^^^^^^
231+
>x : U
232+
> : ^
233+
>undefined : undefined
234+
> : ^^^^^^^^^
235+
236+
return false;
237+
>false : false
238+
> : ^^^^^
239+
}
240+
return x < y;
241+
>x < y : boolean
242+
> : ^^^^^^^
243+
>x : U & ({} | null)
244+
> : ^^^^^^^^^^^^^^^
245+
>y : U
246+
> : ^
247+
}
248+
249+
function f14<T, U>(x: T & U, y: T & U) {
250+
>f14 : <T, U>(x: T & U, y: T & U) => boolean
193251
> : ^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^
194252
>x : T & U
195253
> : ^^^^^
@@ -205,8 +263,8 @@ function f12<T, U>(x: T & U, y: T & U) {
205263
> : ^^^^^
206264
}
207265

208-
function f13<T, U extends T>(x: T & number, y: U & number) {
209-
>f13 : <T, U extends T>(x: T & number, y: U & number) => boolean
266+
function f15<T, U extends T>(x: T & number, y: U & number) {
267+
>f15 : <T, U extends T>(x: T & number, y: U & number) => boolean
210268
> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^
211269
>x : T & number
212270
> : ^^^^^^^^^^
@@ -222,6 +280,45 @@ function f13<T, U extends T>(x: T & number, y: U & number) {
222280
> : ^^^^^^^^^^
223281
}
224282

283+
function f16<T, U extends T>(x: T & U, y: U) {
284+
>f16 : <T, U extends T>(x: T & U, y: U) => boolean
285+
> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^
286+
>x : T & U
287+
> : ^^^^^
288+
>y : U
289+
> : ^
290+
291+
if (x === undefined) {
292+
>x === undefined : boolean
293+
> : ^^^^^^^
294+
>x : T & U
295+
> : ^^^^^
296+
>undefined : undefined
297+
> : ^^^^^^^^^
298+
299+
return false;
300+
>false : false
301+
> : ^^^^^
302+
}
303+
if (y === null) {
304+
>y === null : boolean
305+
> : ^^^^^^^
306+
>y : U
307+
> : ^
308+
309+
return false;
310+
>false : false
311+
> : ^^^^^
312+
}
313+
return x < y;
314+
>x < y : boolean
315+
> : ^^^^^^^
316+
>x : T & U & ({} | null)
317+
> : ^^^^^^^^^^^^^^^^^^^
318+
>y : U & ({} | undefined)
319+
> : ^^^^^^^^^^^^^^^^^^^^
320+
}
321+
225322

226323
function compare<T>(a: T, b: T): boolean {
227324
>compare : <T>(a: T, b: T) => boolean

0 commit comments

Comments
 (0)