Skip to content

Commit d71dd1d

Browse files
authored
fix(48556): throw an error on jsx spread attributes with an invalid type (microsoft#48570)
1 parent 7abdb9e commit d71dd1d

10 files changed

+165
-3
lines changed

Diff for: src/compiler/checker.ts

+1
Original file line numberDiff line numberDiff line change
@@ -27986,6 +27986,7 @@ namespace ts {
2798627986
}
2798727987
}
2798827988
else {
27989+
error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types);
2798927990
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
2799027991
}
2799127992
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
tests/cases/conformance/jsx/0.tsx(6,21): error TS2698: Spread types may only be created from object types.
2+
3+
4+
==== tests/cases/conformance/jsx/0.tsx (1 errors) ====
5+
///<reference path="declaration.d.ts" />
6+
import * as cx from 'classnames';
7+
import * as React from "react";
8+
9+
let buttonProps;
10+
let k = <button {...buttonProps}>
11+
~~~~~~~~~~~
12+
!!! error TS2698: Spread types may only be created from object types.
13+
<span className={cx('class1', { class2: true })} />
14+
</button>;
15+
16+
==== tests/cases/conformance/jsx/declaration.d.ts (0 errors) ====
17+
declare module "classnames";
18+

Diff for: tests/baselines/reference/jsxExcessPropsAndAssignability.errors.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
tests/cases/compiler/jsxExcessPropsAndAssignability.tsx(14,27): error TS2698: Spread types may only be created from object types.
12
tests/cases/compiler/jsxExcessPropsAndAssignability.tsx(16,6): error TS2322: Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<WrapperComponentProps, any, any>> & Readonly<{ children?: ReactNode; }> & Readonly<WrapperComponentProps>'.
23
Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'Readonly<WrapperComponentProps>'.
4+
tests/cases/compiler/jsxExcessPropsAndAssignability.tsx(16,27): error TS2698: Spread types may only be created from object types.
35

46

5-
==== tests/cases/compiler/jsxExcessPropsAndAssignability.tsx (1 errors) ====
7+
==== tests/cases/compiler/jsxExcessPropsAndAssignability.tsx (3 errors) ====
68
/// <reference path="/.lib/react16.d.ts" />
79

810
import * as React from 'react';
@@ -17,10 +19,14 @@ tests/cases/compiler/jsxExcessPropsAndAssignability.tsx(16,6): error TS2322: Typ
1719

1820
// Expected no error, got none - good
1921
<WrapperComponent {...props} myProp={'1000000'} />;
22+
~~~~~
23+
!!! error TS2698: Spread types may only be created from object types.
2024
// Expected error, but got none - bad!
2125
<WrapperComponent {...props} myProp={1000000} />;
2226
~~~~~~~~~~~~~~~~
2327
!!! error TS2322: Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<WrapperComponentProps, any, any>> & Readonly<{ children?: ReactNode; }> & Readonly<WrapperComponentProps>'.
2428
!!! error TS2322: Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'Readonly<WrapperComponentProps>'.
29+
~~~~~
30+
!!! error TS2698: Spread types may only be created from object types.
2531
};
2632

Diff for: tests/baselines/reference/jsxNamespacePrefixInName.errors.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ tests/cases/compiler/jsxNamespacePrefixInName.tsx(21,21): error TS1003: Identifi
1919
tests/cases/compiler/jsxNamespacePrefixInName.tsx(22,26): error TS1003: Identifier expected.
2020
tests/cases/compiler/jsxNamespacePrefixInName.tsx(22,27): error TS1003: Identifier expected.
2121
tests/cases/compiler/jsxNamespacePrefixInName.tsx(22,29): error TS1005: '...' expected.
22+
tests/cases/compiler/jsxNamespacePrefixInName.tsx(22,29): error TS2698: Spread types may only be created from object types.
2223
tests/cases/compiler/jsxNamespacePrefixInName.tsx(24,21): error TS1109: Expression expected.
2324
tests/cases/compiler/jsxNamespacePrefixInName.tsx(24,22): error TS1109: Expression expected.
2425
tests/cases/compiler/jsxNamespacePrefixInName.tsx(24,25): error TS1005: ',' expected.
@@ -29,7 +30,7 @@ tests/cases/compiler/jsxNamespacePrefixInName.tsx(24,42): error TS1109: Expressi
2930
tests/cases/compiler/jsxNamespacePrefixInName.tsx(25,24): error TS1003: Identifier expected.
3031

3132

32-
==== tests/cases/compiler/jsxNamespacePrefixInName.tsx (29 errors) ====
33+
==== tests/cases/compiler/jsxNamespacePrefixInName.tsx (30 errors) ====
3334
var justElement1 = <a:element />;
3435
var justElement2 = <a:element></a:element>;
3536
var justElement3 = <a:element attr={"value"}></a:element>;
@@ -94,6 +95,8 @@ tests/cases/compiler/jsxNamespacePrefixInName.tsx(25,24): error TS1003: Identifi
9495
!!! error TS1003: Identifier expected.
9596
~~~~~~~
9697
!!! error TS1005: '...' expected.
98+
~~~~~~~
99+
!!! error TS2698: Spread types may only be created from object types.
97100

98101
var beginOfIdent1 = <:a attr={"value"} />;
99102
~

Diff for: tests/baselines/reference/jsxNamespacePrefixInNameReact.errors.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(23,21): error TS1003: Ide
1919
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(24,26): error TS1003: Identifier expected.
2020
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(24,27): error TS1003: Identifier expected.
2121
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(24,29): error TS1005: '...' expected.
22+
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(24,29): error TS2698: Spread types may only be created from object types.
2223
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(26,21): error TS1109: Expression expected.
2324
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(26,22): error TS1109: Expression expected.
2425
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(26,25): error TS1005: ',' expected.
@@ -29,7 +30,7 @@ tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(26,42): error TS1109: Exp
2930
tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(27,24): error TS1003: Identifier expected.
3031

3132

32-
==== tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx (29 errors) ====
33+
==== tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx (30 errors) ====
3334
declare var React: any;
3435

3536
var justElement1 = <a:element />;
@@ -96,6 +97,8 @@ tests/cases/compiler/jsxNamespacePrefixInNameReact.tsx(27,24): error TS1003: Ide
9697
!!! error TS1003: Identifier expected.
9798
~~~~~~~
9899
!!! error TS1005: '...' expected.
100+
~~~~~~~
101+
!!! error TS2698: Spread types may only be created from object types.
99102

100103
var beginOfIdent1 = <:a attr={"value"} />;
101104
~
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
tests/cases/conformance/jsx/a.tsx(9,21): error TS2698: Spread types may only be created from object types.
2+
tests/cases/conformance/jsx/a.tsx(10,21): error TS2698: Spread types may only be created from object types.
3+
tests/cases/conformance/jsx/a.tsx(11,21): error TS2698: Spread types may only be created from object types.
4+
5+
6+
==== tests/cases/conformance/jsx/a.tsx (3 errors) ====
7+
namespace JSX {
8+
export interface IntrinsicElements { [key: string]: any }
9+
}
10+
11+
const a = {} as never;
12+
const b = null;
13+
const c = undefined;
14+
15+
const d = <div { ...a } />
16+
~
17+
!!! error TS2698: Spread types may only be created from object types.
18+
const e = <div { ...b } />
19+
~
20+
!!! error TS2698: Spread types may only be created from object types.
21+
const f = <div { ...c } />
22+
~
23+
!!! error TS2698: Spread types may only be created from object types.
24+

Diff for: tests/baselines/reference/tsxSpreadInvalidType.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [a.tsx]
2+
namespace JSX {
3+
export interface IntrinsicElements { [key: string]: any }
4+
}
5+
6+
const a = {} as never;
7+
const b = null;
8+
const c = undefined;
9+
10+
const d = <div { ...a } />
11+
const e = <div { ...b } />
12+
const f = <div { ...c } />
13+
14+
15+
//// [a.jsx]
16+
"use strict";
17+
var a = {};
18+
var b = null;
19+
var c = undefined;
20+
var d = <div {...a}/>;
21+
var e = <div {...b}/>;
22+
var f = <div {...c}/>;
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/conformance/jsx/a.tsx ===
2+
namespace JSX {
3+
>JSX : Symbol(JSX, Decl(a.tsx, 0, 0))
4+
5+
export interface IntrinsicElements { [key: string]: any }
6+
>IntrinsicElements : Symbol(IntrinsicElements, Decl(a.tsx, 0, 15))
7+
>key : Symbol(key, Decl(a.tsx, 1, 42))
8+
}
9+
10+
const a = {} as never;
11+
>a : Symbol(a, Decl(a.tsx, 4, 5))
12+
13+
const b = null;
14+
>b : Symbol(b, Decl(a.tsx, 5, 5))
15+
16+
const c = undefined;
17+
>c : Symbol(c, Decl(a.tsx, 6, 5))
18+
>undefined : Symbol(undefined)
19+
20+
const d = <div { ...a } />
21+
>d : Symbol(d, Decl(a.tsx, 8, 5))
22+
>div : Symbol(JSX.IntrinsicElements, Decl(a.tsx, 0, 15))
23+
>a : Symbol(a, Decl(a.tsx, 4, 5))
24+
25+
const e = <div { ...b } />
26+
>e : Symbol(e, Decl(a.tsx, 9, 5))
27+
>div : Symbol(JSX.IntrinsicElements, Decl(a.tsx, 0, 15))
28+
>b : Symbol(b, Decl(a.tsx, 5, 5))
29+
30+
const f = <div { ...c } />
31+
>f : Symbol(f, Decl(a.tsx, 10, 5))
32+
>div : Symbol(JSX.IntrinsicElements, Decl(a.tsx, 0, 15))
33+
>c : Symbol(c, Decl(a.tsx, 6, 5))
34+

Diff for: tests/baselines/reference/tsxSpreadInvalidType.types

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/conformance/jsx/a.tsx ===
2+
namespace JSX {
3+
export interface IntrinsicElements { [key: string]: any }
4+
>key : string
5+
}
6+
7+
const a = {} as never;
8+
>a : never
9+
>{} as never : never
10+
>{} : {}
11+
12+
const b = null;
13+
>b : null
14+
>null : null
15+
16+
const c = undefined;
17+
>c : undefined
18+
>undefined : undefined
19+
20+
const d = <div { ...a } />
21+
>d : any
22+
><div { ...a } /> : any
23+
>div : any
24+
>a : never
25+
26+
const e = <div { ...b } />
27+
>e : any
28+
><div { ...b } /> : any
29+
>div : any
30+
>b : null
31+
32+
const f = <div { ...c } />
33+
>f : any
34+
><div { ...c } /> : any
35+
>div : any
36+
>c : undefined
37+

Diff for: tests/cases/conformance/jsx/tsxSpreadInvalidType.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @jsx: preserve
2+
// @strict: true
3+
// @filename: a.tsx
4+
namespace JSX {
5+
export interface IntrinsicElements { [key: string]: any }
6+
}
7+
8+
const a = {} as never;
9+
const b = null;
10+
const c = undefined;
11+
12+
const d = <div { ...a } />
13+
const e = <div { ...b } />
14+
const f = <div { ...c } />

0 commit comments

Comments
 (0)