Remove error when spreading optional any (#37757)

Previously, spreading an optional any gave a bogus error when the name
conflicted with earlier properties in the object literal. Now the code
checks any types for optionality before issuing the error.

Fixes #37740
This commit is contained in:
Nathan Shively-Sanders
2020-04-02 15:04:45 -07:00
committed by GitHub
parent 696413749b
commit 527f467926
6 changed files with 81 additions and 2 deletions

View File

@@ -23233,7 +23233,8 @@ namespace ts {
function checkSpreadPropOverrides(type: Type, props: SymbolTable, spread: SpreadAssignment | JsxSpreadAttribute) {
for (const right of getPropertiesOfType(type)) {
const left = props.get(right.escapedName);
if (left && !maybeTypeOfKind(getTypeOfSymbol(right), TypeFlags.Nullable)) {
const rightType = getTypeOfSymbol(right);
if (left && !maybeTypeOfKind(rightType, TypeFlags.Nullable) && !(maybeTypeOfKind(rightType, TypeFlags.Any) && right.flags & SymbolFlags.Optional)) {
const diagnostic = error(left.valueDeclaration, Diagnostics._0_is_specified_more_than_once_so_this_usage_will_be_overwritten, unescapeLeadingUnderscores(left.escapedName));
addRelatedInfo(diagnostic, createDiagnosticForNode(spread, Diagnostics.This_spread_always_overwrites_this_property));
}

View File

@@ -1,9 +1,10 @@
tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(3,17): error TS2783: 'b' is specified more than once, so this usage will be overwritten.
tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(15,14): error TS2783: 'x' is specified more than once, so this usage will be overwritten.
tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(24,14): error TS2783: 'command' is specified more than once, so this usage will be overwritten.
tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(28,14): error TS2783: 'a' is specified more than once, so this usage will be overwritten.
==== tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts (3 errors) ====
==== tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts (4 errors) ====
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab } // error
@@ -38,4 +39,15 @@ tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(24,14): e
!!! error TS2783: 'command' is specified more than once, so this usage will be overwritten.
!!! related TS2785 tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts:24:67: This spread always overwrites this property.
}
function l(anyrequired: { a: any }) {
return { a: 'zzz', ...anyrequired } // error
~~~~~~~~
!!! error TS2783: 'a' is specified more than once, so this usage will be overwritten.
!!! related TS2785 tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts:28:24: This spread always overwrites this property.
}
function m(anyoptional: { a?: any }) {
return { a: 'zzz', ...anyoptional } // ok
}

View File

@@ -24,6 +24,14 @@ function j() {
function k(t: { command: string, ok: string }) {
return { command: "hi", ...{ spoiler: true }, spoiler2: true, ...t } // error
}
function l(anyrequired: { a: any }) {
return { a: 'zzz', ...anyrequired } // error
}
function m(anyoptional: { a?: any }) {
return { a: 'zzz', ...anyoptional } // ok
}
//// [spreadOverwritesPropertyStrict.js]
@@ -62,3 +70,9 @@ function j() {
function k(t) {
return __assign(__assign(__assign({ command: "hi" }, { spoiler: true }), { spoiler2: true }), t); // error
}
function l(anyrequired) {
return __assign({ a: 'zzz' }, anyrequired); // error
}
function m(anyoptional) {
return __assign({ a: 'zzz' }, anyoptional); // ok
}

View File

@@ -94,3 +94,23 @@ function k(t: { command: string, ok: string }) {
>t : Symbol(t, Decl(spreadOverwritesPropertyStrict.ts, 22, 11))
}
function l(anyrequired: { a: any }) {
>l : Symbol(l, Decl(spreadOverwritesPropertyStrict.ts, 24, 1))
>anyrequired : Symbol(anyrequired, Decl(spreadOverwritesPropertyStrict.ts, 26, 11))
>a : Symbol(a, Decl(spreadOverwritesPropertyStrict.ts, 26, 25))
return { a: 'zzz', ...anyrequired } // error
>a : Symbol(a, Decl(spreadOverwritesPropertyStrict.ts, 27, 12))
>anyrequired : Symbol(anyrequired, Decl(spreadOverwritesPropertyStrict.ts, 26, 11))
}
function m(anyoptional: { a?: any }) {
>m : Symbol(m, Decl(spreadOverwritesPropertyStrict.ts, 28, 1))
>anyoptional : Symbol(anyoptional, Decl(spreadOverwritesPropertyStrict.ts, 29, 11))
>a : Symbol(a, Decl(spreadOverwritesPropertyStrict.ts, 29, 25))
return { a: 'zzz', ...anyoptional } // ok
>a : Symbol(a, Decl(spreadOverwritesPropertyStrict.ts, 30, 12))
>anyoptional : Symbol(anyoptional, Decl(spreadOverwritesPropertyStrict.ts, 29, 11))
}

View File

@@ -124,3 +124,27 @@ function k(t: { command: string, ok: string }) {
>t : { command: string; ok: string; }
}
function l(anyrequired: { a: any }) {
>l : (anyrequired: { a: any;}) => { a: any; }
>anyrequired : { a: any; }
>a : any
return { a: 'zzz', ...anyrequired } // error
>{ a: 'zzz', ...anyrequired } : { a: any; }
>a : string
>'zzz' : "zzz"
>anyrequired : { a: any; }
}
function m(anyoptional: { a?: any }) {
>m : (anyoptional: { a?: any;}) => { a: any; }
>anyoptional : { a?: any; }
>a : any
return { a: 'zzz', ...anyoptional } // ok
>{ a: 'zzz', ...anyoptional } : { a: any; }
>a : string
>'zzz' : "zzz"
>anyoptional : { a?: any; }
}

View File

@@ -24,3 +24,11 @@ function j() {
function k(t: { command: string, ok: string }) {
return { command: "hi", ...{ spoiler: true }, spoiler2: true, ...t } // error
}
function l(anyrequired: { a: any }) {
return { a: 'zzz', ...anyrequired } // error
}
function m(anyoptional: { a?: any }) {
return { a: 'zzz', ...anyoptional } // ok
}