Skip to content

Commit 634beb5

Browse files
author
Orta
authored
Merge pull request microsoft#32969 from collin5/b30851-2
Restrict spreading for unknown Type with non object constraint
2 parents b57b5fe + 0341c2f commit 634beb5

File tree

6 files changed

+62
-40
lines changed

6 files changed

+62
-40
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19878,7 +19878,7 @@ namespace ts {
1987819878
return isValidSpreadType(constraint);
1987919879
}
1988019880
}
19881-
return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) ||
19881+
return !!(type.flags & (TypeFlags.Any | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) ||
1988219882
getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
1988319883
type.flags & TypeFlags.UnionOrIntersection && every((<UnionOrIntersectionType>type).types, isValidSpreadType));
1988419884
}

tests/baselines/reference/unknownType1.errors.txt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ tests/cases/conformance/types/unknown/unknownType1.ts(120,9): error TS2322: Type
2121
tests/cases/conformance/types/unknown/unknownType1.ts(128,5): error TS2322: Type 'number[]' is not assignable to type '{ [x: string]: unknown; }'.
2222
Index signature is missing in type 'number[]'.
2323
tests/cases/conformance/types/unknown/unknownType1.ts(129,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'.
24-
tests/cases/conformance/types/unknown/unknownType1.ts(149,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
25-
tests/cases/conformance/types/unknown/unknownType1.ts(155,14): error TS2700: Rest types may only be created from object types.
26-
tests/cases/conformance/types/unknown/unknownType1.ts(161,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
27-
tests/cases/conformance/types/unknown/unknownType1.ts(170,9): error TS2322: Type 'U' is not assignable to type '{}'.
24+
tests/cases/conformance/types/unknown/unknownType1.ts(143,29): error TS2698: Spread types may only be created from object types.
25+
tests/cases/conformance/types/unknown/unknownType1.ts(144,29): error TS2698: Spread types may only be created from object types.
26+
tests/cases/conformance/types/unknown/unknownType1.ts(150,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
27+
tests/cases/conformance/types/unknown/unknownType1.ts(156,14): error TS2700: Rest types may only be created from object types.
28+
tests/cases/conformance/types/unknown/unknownType1.ts(162,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor.
29+
tests/cases/conformance/types/unknown/unknownType1.ts(171,9): error TS2322: Type 'U' is not assignable to type '{}'.
2830
Type 'unknown' is not assignable to type '{}'.
29-
tests/cases/conformance/types/unknown/unknownType1.ts(180,5): error TS2322: Type 'T' is not assignable to type '{}'.
31+
tests/cases/conformance/types/unknown/unknownType1.ts(181,5): error TS2322: Type 'T' is not assignable to type '{}'.
3032
Type 'unknown' is not assignable to type '{}'.
3133

3234

33-
==== tests/cases/conformance/types/unknown/unknownType1.ts (25 errors) ====
35+
==== tests/cases/conformance/types/unknown/unknownType1.ts (27 errors) ====
3436
// In an intersection everything absorbs unknown
3537

3638
type T00 = unknown & null; // null
@@ -217,7 +219,12 @@ tests/cases/conformance/types/unknown/unknownType1.ts(180,5): error TS2322: Type
217219
function f26(x: {}, y: unknown, z: any) {
218220
let o1 = { a: 42, ...x }; // { a: number }
219221
let o2 = { a: 42, ...x, ...y }; // unknown
222+
~~~~
223+
!!! error TS2698: Spread types may only be created from object types.
220224
let o3 = { a: 42, ...x, ...y, ...z }; // any
225+
~~~~
226+
!!! error TS2698: Spread types may only be created from object types.
227+
let o4 = { a: 42, ...z }; // any
221228
}
222229

223230
// Functions with unknown return type don't need return expressions

tests/baselines/reference/unknownType1.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ function f26(x: {}, y: unknown, z: any) {
143143
let o1 = { a: 42, ...x }; // { a: number }
144144
let o2 = { a: 42, ...x, ...y }; // unknown
145145
let o3 = { a: 42, ...x, ...y, ...z }; // any
146+
let o4 = { a: 42, ...z }; // any
146147
}
147148

148149
// Functions with unknown return type don't need return expressions
@@ -281,6 +282,7 @@ function f26(x, y, z) {
281282
var o1 = __assign({ a: 42 }, x); // { a: number }
282283
var o2 = __assign(__assign({ a: 42 }, x), y); // unknown
283284
var o3 = __assign(__assign(__assign({ a: 42 }, x), y), z); // any
285+
var o4 = __assign({ a: 42 }, z); // any
284286
}
285287
// Functions with unknown return type don't need return expressions
286288
function f27() {

tests/baselines/reference/unknownType1.symbols

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -372,82 +372,87 @@ function f26(x: {}, y: unknown, z: any) {
372372
>a : Symbol(a, Decl(unknownType1.ts, 143, 14))
373373
>x : Symbol(x, Decl(unknownType1.ts, 140, 13))
374374
>y : Symbol(y, Decl(unknownType1.ts, 140, 19))
375+
>z : Symbol(z, Decl(unknownType1.ts, 140, 31))
376+
377+
let o4 = { a: 42, ...z }; // any
378+
>o4 : Symbol(o4, Decl(unknownType1.ts, 144, 7))
379+
>a : Symbol(a, Decl(unknownType1.ts, 144, 14))
375380
>z : Symbol(z, Decl(unknownType1.ts, 140, 31))
376381
}
377382

378383
// Functions with unknown return type don't need return expressions
379384

380385
function f27(): unknown {
381-
>f27 : Symbol(f27, Decl(unknownType1.ts, 144, 1))
386+
>f27 : Symbol(f27, Decl(unknownType1.ts, 145, 1))
382387
}
383388

384389
// Rest type cannot be created from unknown
385390

386391
function f28(x: unknown) {
387-
>f28 : Symbol(f28, Decl(unknownType1.ts, 149, 1))
388-
>x : Symbol(x, Decl(unknownType1.ts, 153, 13))
392+
>f28 : Symbol(f28, Decl(unknownType1.ts, 150, 1))
393+
>x : Symbol(x, Decl(unknownType1.ts, 154, 13))
389394

390395
let { ...a } = x; // Error
391-
>a : Symbol(a, Decl(unknownType1.ts, 154, 9))
392-
>x : Symbol(x, Decl(unknownType1.ts, 153, 13))
396+
>a : Symbol(a, Decl(unknownType1.ts, 155, 9))
397+
>x : Symbol(x, Decl(unknownType1.ts, 154, 13))
393398
}
394399

395400
// Class properties of type unknown don't need definite assignment
396401

397402
class C1 {
398-
>C1 : Symbol(C1, Decl(unknownType1.ts, 155, 1))
403+
>C1 : Symbol(C1, Decl(unknownType1.ts, 156, 1))
399404

400405
a: string; // Error
401-
>a : Symbol(C1.a, Decl(unknownType1.ts, 159, 10))
406+
>a : Symbol(C1.a, Decl(unknownType1.ts, 160, 10))
402407

403408
b: unknown;
404-
>b : Symbol(C1.b, Decl(unknownType1.ts, 160, 14))
409+
>b : Symbol(C1.b, Decl(unknownType1.ts, 161, 14))
405410

406411
c: any;
407-
>c : Symbol(C1.c, Decl(unknownType1.ts, 161, 15))
412+
>c : Symbol(C1.c, Decl(unknownType1.ts, 162, 15))
408413
}
409414

410415
// Type parameter with explicit 'unknown' constraint not assignable to '{}'
411416

412417
function f30<T, U extends unknown>(t: T, u: U) {
413-
>f30 : Symbol(f30, Decl(unknownType1.ts, 163, 1))
414-
>T : Symbol(T, Decl(unknownType1.ts, 167, 13))
415-
>U : Symbol(U, Decl(unknownType1.ts, 167, 15))
416-
>t : Symbol(t, Decl(unknownType1.ts, 167, 35))
417-
>T : Symbol(T, Decl(unknownType1.ts, 167, 13))
418-
>u : Symbol(u, Decl(unknownType1.ts, 167, 40))
419-
>U : Symbol(U, Decl(unknownType1.ts, 167, 15))
418+
>f30 : Symbol(f30, Decl(unknownType1.ts, 164, 1))
419+
>T : Symbol(T, Decl(unknownType1.ts, 168, 13))
420+
>U : Symbol(U, Decl(unknownType1.ts, 168, 15))
421+
>t : Symbol(t, Decl(unknownType1.ts, 168, 35))
422+
>T : Symbol(T, Decl(unknownType1.ts, 168, 13))
423+
>u : Symbol(u, Decl(unknownType1.ts, 168, 40))
424+
>U : Symbol(U, Decl(unknownType1.ts, 168, 15))
420425

421426
let x: {} = t;
422-
>x : Symbol(x, Decl(unknownType1.ts, 168, 7))
423-
>t : Symbol(t, Decl(unknownType1.ts, 167, 35))
427+
>x : Symbol(x, Decl(unknownType1.ts, 169, 7))
428+
>t : Symbol(t, Decl(unknownType1.ts, 168, 35))
424429

425430
let y: {} = u;
426-
>y : Symbol(y, Decl(unknownType1.ts, 169, 7))
427-
>u : Symbol(u, Decl(unknownType1.ts, 167, 40))
431+
>y : Symbol(y, Decl(unknownType1.ts, 170, 7))
432+
>u : Symbol(u, Decl(unknownType1.ts, 168, 40))
428433
}
429434

430435
// Repro from #26796
431436

432437
type Test1 = [unknown] extends [{}] ? true : false; // false
433-
>Test1 : Symbol(Test1, Decl(unknownType1.ts, 170, 1))
438+
>Test1 : Symbol(Test1, Decl(unknownType1.ts, 171, 1))
434439

435440
type IsDefinitelyDefined<T extends unknown> = [T] extends [{}] ? true : false;
436-
>IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 174, 51))
437-
>T : Symbol(T, Decl(unknownType1.ts, 175, 25))
438-
>T : Symbol(T, Decl(unknownType1.ts, 175, 25))
441+
>IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 175, 51))
442+
>T : Symbol(T, Decl(unknownType1.ts, 176, 25))
443+
>T : Symbol(T, Decl(unknownType1.ts, 176, 25))
439444

440445
type Test2 = IsDefinitelyDefined<unknown>; // false
441-
>Test2 : Symbol(Test2, Decl(unknownType1.ts, 175, 78))
442-
>IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 174, 51))
446+
>Test2 : Symbol(Test2, Decl(unknownType1.ts, 176, 78))
447+
>IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 175, 51))
443448

444449
function oops<T extends unknown>(arg: T): {} {
445-
>oops : Symbol(oops, Decl(unknownType1.ts, 176, 42))
446-
>T : Symbol(T, Decl(unknownType1.ts, 178, 14))
447-
>arg : Symbol(arg, Decl(unknownType1.ts, 178, 33))
448-
>T : Symbol(T, Decl(unknownType1.ts, 178, 14))
450+
>oops : Symbol(oops, Decl(unknownType1.ts, 177, 42))
451+
>T : Symbol(T, Decl(unknownType1.ts, 179, 14))
452+
>arg : Symbol(arg, Decl(unknownType1.ts, 179, 33))
453+
>T : Symbol(T, Decl(unknownType1.ts, 179, 14))
449454

450455
return arg; // Error
451-
>arg : Symbol(arg, Decl(unknownType1.ts, 178, 33))
456+
>arg : Symbol(arg, Decl(unknownType1.ts, 179, 33))
452457
}
453458

tests/baselines/reference/unknownType1.types

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,8 @@ function f26(x: {}, y: unknown, z: any) {
404404
>x : {}
405405

406406
let o2 = { a: 42, ...x, ...y }; // unknown
407-
>o2 : unknown
408-
>{ a: 42, ...x, ...y } : unknown
407+
>o2 : any
408+
>{ a: 42, ...x, ...y } : any
409409
>a : number
410410
>42 : 42
411411
>x : {}
@@ -418,6 +418,13 @@ function f26(x: {}, y: unknown, z: any) {
418418
>42 : 42
419419
>x : {}
420420
>y : unknown
421+
>z : any
422+
423+
let o4 = { a: 42, ...z }; // any
424+
>o4 : any
425+
>{ a: 42, ...z } : any
426+
>a : number
427+
>42 : 42
421428
>z : any
422429
}
423430

tests/cases/conformance/types/unknown/unknownType1.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ function f26(x: {}, y: unknown, z: any) {
144144
let o1 = { a: 42, ...x }; // { a: number }
145145
let o2 = { a: 42, ...x, ...y }; // unknown
146146
let o3 = { a: 42, ...x, ...y, ...z }; // any
147+
let o4 = { a: 42, ...z }; // any
147148
}
148149

149150
// Functions with unknown return type don't need return expressions

0 commit comments

Comments
 (0)