Fixed an issue with JSX spreads sometimes reported as always overriding other attributes

This commit is contained in:
Mateusz Burzyński 2024-10-27 10:17:15 +01:00
Родитель 2ac4cb78d6
Коммит d6ecddb122
6 изменённых файлов: 202 добавлений и 2 удалений

Просмотреть файл

@ -33017,10 +33017,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
hasSpreadAnyType = true;
}
if (isValidSpreadType(exprType)) {
spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false);
const mergedType = tryMergeUnionOfObjectTypeAndEmptyObject(exprType, /*readonly*/ false);
if (allAttributesTable) {
checkSpreadPropOverrides(exprType, allAttributesTable, attributeDecl);
checkSpreadPropOverrides(mergedType, allAttributesTable, attributeDecl);
}
if (isErrorType(spread)) {
continue;
}
spread = getSpreadType(spread, mergedType, attributes.symbol, objectFlags, /*readonly*/ false);
}
else {
error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types);

Просмотреть файл

@ -55,4 +55,25 @@ file.tsx(22,23): error TS2783: 'd' is specified more than once, so this usage wi
~~~~~
!!! error TS2783: 'd' is specified more than once, so this usage will be overwritten.
!!! related TS2785 file.tsx:22:40: This spread always overwrites this property.
// https://github.com/microsoft/TypeScript/issues/60343
function Component60343(props: any) {
return <div></div>;
}
function Test60343({ shouldOverride }: { shouldOverride: boolean }) {
return (
<Component60343
a={false}
b={false} // no error
c={false}
{...(shouldOverride
? {
b: true,
}
: {})}
/>
);
}

Просмотреть файл

@ -23,6 +23,27 @@ const b1 = <Foo a={1} {...props}></Foo>;
const b2 = <Foo a={1} b={2} {...props}></Foo>;
const b3 = <Foo a={1} d={1} {...props} {...{ d: 1 }}></Foo>;
const b4 = <Foo a={1} d={1} {...props} {...{ a: 1, d: 1 }}></Foo>;
// https://github.com/microsoft/TypeScript/issues/60343
function Component60343(props: any) {
return <div></div>;
}
function Test60343({ shouldOverride }: { shouldOverride: boolean }) {
return (
<Component60343
a={false}
b={false} // no error
c={false}
{...(shouldOverride
? {
b: true,
}
: {})}
/>
);
}
//// [file.jsx]
@ -39,3 +60,16 @@ var b1 = <Foo a={1} {...props}></Foo>;
var b2 = <Foo a={1} b={2} {...props}></Foo>;
var b3 = <Foo a={1} d={1} {...props} {...{ d: 1 }}></Foo>;
var b4 = <Foo a={1} d={1} {...props} {...{ a: 1, d: 1 }}></Foo>;
// https://github.com/microsoft/TypeScript/issues/60343
function Component60343(props) {
return <div></div>;
}
function Test60343(_a) {
var shouldOverride = _a.shouldOverride;
return (<Component60343 a={false} b={false} // no error
c={false} {...(shouldOverride
? {
b: true,
}
: {})}/>);
}

Просмотреть файл

@ -86,3 +86,44 @@ const b4 = <Foo a={1} d={1} {...props} {...{ a: 1, d: 1 }}></Foo>;
>d : Symbol(d, Decl(file.tsx, 21, 50))
>Foo : Symbol(Foo, Decl(file.tsx, 11, 5))
// https://github.com/microsoft/TypeScript/issues/60343
function Component60343(props: any) {
>Component60343 : Symbol(Component60343, Decl(file.tsx, 21, 66))
>props : Symbol(props, Decl(file.tsx, 25, 24))
return <div></div>;
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
}
function Test60343({ shouldOverride }: { shouldOverride: boolean }) {
>Test60343 : Symbol(Test60343, Decl(file.tsx, 27, 1))
>shouldOverride : Symbol(shouldOverride, Decl(file.tsx, 29, 20))
>shouldOverride : Symbol(shouldOverride, Decl(file.tsx, 29, 40))
return (
<Component60343
>Component60343 : Symbol(Component60343, Decl(file.tsx, 21, 66))
a={false}
>a : Symbol(a, Decl(file.tsx, 31, 19))
b={false} // no error
>b : Symbol(b, Decl(file.tsx, 32, 15))
c={false}
>c : Symbol(c, Decl(file.tsx, 33, 15))
{...(shouldOverride
>shouldOverride : Symbol(shouldOverride, Decl(file.tsx, 29, 20))
? {
b: true,
>b : Symbol(b, Decl(file.tsx, 36, 11))
}
: {})}
/>
);
}

Просмотреть файл

@ -180,3 +180,82 @@ const b4 = <Foo a={1} d={1} {...props} {...{ a: 1, d: 1 }}></Foo>;
>Foo : (props: Props) => JSX.Element
> : ^ ^^ ^^^^^^^^^^^^^^^^
// https://github.com/microsoft/TypeScript/issues/60343
function Component60343(props: any) {
>Component60343 : (props: any) => JSX.Element
> : ^ ^^ ^^^^^^^^^^^^^^^^
>props : any
> : ^^^
return <div></div>;
><div></div> : JSX.Element
> : ^^^^^^^^^^^
>div : any
> : ^^^
>div : any
> : ^^^
}
function Test60343({ shouldOverride }: { shouldOverride: boolean }) {
>Test60343 : ({ shouldOverride }: { shouldOverride: boolean; }) => JSX.Element
> : ^ ^^ ^^^^^^^^^^^^^^^^
>shouldOverride : boolean
> : ^^^^^^^
>shouldOverride : boolean
> : ^^^^^^^
return (
>( <Component60343 a={false} b={false} // no error c={false} {...(shouldOverride ? { b: true, } : {})} /> ) : JSX.Element
> : ^^^^^^^^^^^
<Component60343
><Component60343 a={false} b={false} // no error c={false} {...(shouldOverride ? { b: true, } : {})} /> : JSX.Element
> : ^^^^^^^^^^^
>Component60343 : (props: any) => JSX.Element
> : ^ ^^ ^^^^^^^^^^^^^^^^
a={false}
>a : boolean
> : ^^^^^^^
>false : false
> : ^^^^^
b={false} // no error
>b : boolean
> : ^^^^^^^
>false : false
> : ^^^^^
c={false}
>c : boolean
> : ^^^^^^^
>false : false
> : ^^^^^
{...(shouldOverride
>(shouldOverride ? { b: true, } : {}) : { b: boolean; } | {}
> : ^^^^^^^^^^^^^^^^^^^^
>shouldOverride ? { b: true, } : {} : { b: boolean; } | {}
> : ^^^^^^^^^^^^^^^^^^^^
>shouldOverride : boolean
> : ^^^^^^^
? {
>{ b: true, } : { b: boolean; }
> : ^^^^^^^^^^^^^^^
b: true,
>b : boolean
> : ^^^^^^^
>true : true
> : ^^^^
}
: {})}
>{} : {}
> : ^^
/>
);
}

Просмотреть файл

@ -27,3 +27,24 @@ const b1 = <Foo a={1} {...props}></Foo>;
const b2 = <Foo a={1} b={2} {...props}></Foo>;
const b3 = <Foo a={1} d={1} {...props} {...{ d: 1 }}></Foo>;
const b4 = <Foo a={1} d={1} {...props} {...{ a: 1, d: 1 }}></Foo>;
// https://github.com/microsoft/TypeScript/issues/60343
function Component60343(props: any) {
return <div></div>;
}
function Test60343({ shouldOverride }: { shouldOverride: boolean }) {
return (
<Component60343
a={false}
b={false} // no error
c={false}
{...(shouldOverride
? {
b: true,
}
: {})}
/>
);
}