Quck and dirty fix for union problems

Doesn't fix JSX problems
This commit is contained in:
Nathan Shively-Sanders 2018-10-12 08:33:30 -07:00
parent aa7247bd74
commit ed7a75b379
15 changed files with 140 additions and 79 deletions

View file

@ -9806,7 +9806,7 @@ namespace ts {
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, typeFlags: TypeFlags, objectFlags: ObjectFlags): Type {
function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, typeFlags: TypeFlags, objectFlags: ObjectFlags, isUnion?: boolean): Type {
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
@ -9820,10 +9820,10 @@ namespace ts {
return left;
}
if (left.flags & TypeFlags.Union) {
return mapType(left, t => getSpreadType(t, right, symbol, typeFlags, objectFlags));
return mapType(left, t => getSpreadType(t, right, symbol, typeFlags, objectFlags, isUnion));
}
if (right.flags & TypeFlags.Union) {
return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags));
return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags, true));
}
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
return left;
@ -9870,7 +9870,12 @@ namespace ts {
result.nameType = leftProp.nameType;
members.set(leftProp.escapedName, result);
}
else if (symbol && shouldCheckAsExcessProperty(leftProp, symbol) && !shouldCheckAsExcessProperty(rightProp, symbol)) {
else if (strictNullChecks &&
!isUnion &&
symbol &&
shouldCheckAsExcessProperty(leftProp, symbol) &&
!shouldCheckAsExcessProperty(rightProp, symbol) &&
!(getFalsyFlags(rightType) & TypeFlags.Nullable)) {
error(leftProp.valueDeclaration, Diagnostics._0_is_overwritten_by_a_later_spread, unescapeLeadingUnderscores(leftProp.escapedName));
}
}

View file

@ -1,33 +0,0 @@
tests/cases/conformance/jsx/file.tsx(12,46): error TS2735: 'children' is overwritten by a later spread.
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
import React = require('react');
interface ButtonProp {
a: number,
b: string,
children: Button;
}
class Button extends React.Component<ButtonProp, any> {
render() {
// Error children are specified twice
return (<InnerButton {...this.props} children="hi">
~~~~~~~~~~~~~
!!! error TS2735: 'children' is overwritten by a later spread.
<div>Hello World</div>
</InnerButton>);
}
}
interface InnerButtonProp {
a: number
}
class InnerButton extends React.Component<InnerButtonProp, any> {
render() {
return (<button>Hello</button>);
}
}

View file

@ -1,6 +1,5 @@
tests/cases/conformance/jsx/file.tsx(14,10): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
Property 'children' is missing in type '{ a: number; b: string; }'.
tests/cases/conformance/jsx/file.tsx(17,25): error TS2735: 'children' is overwritten by a later spread.
tests/cases/conformance/jsx/file.tsx(31,6): error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string | Element'.
@ -23,7 +22,7 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
Property 'type' is missing in type 'Element[]'.
==== tests/cases/conformance/jsx/file.tsx (6 errors) ====
==== tests/cases/conformance/jsx/file.tsx (5 errors) ====
import React = require('react');
interface Prop {
@ -44,8 +43,6 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
let k0 =
<Comp a={10} b="hi" children="Random" >
~~~~~~~~~~~~~~~~~
!!! error TS2735: 'children' is overwritten by a later spread.
hi hi hi!
</Comp>;

View file

@ -5,15 +5,8 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(23,1): error TS2322
Property 'b' is missing in type '{ s: string; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,1): error TS2322: Type '{ b: boolean; }' is not assignable to type '{ s: string; b: boolean; }'.
Property 's' is missing in type '{ b: boolean; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(27,20): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(27,36): error TS2300: Duplicate identifier 'b'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(27,53): error TS2300: Duplicate identifier 'b'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(31,7): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(36,7): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(38,14): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(40,53): error TS2735: 'd' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,7): error TS2735: 'a' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(44,37): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(47,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(48,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(49,20): error TS2698: Spread types may only be created from object types.
@ -27,7 +20,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(77,14): error TS269
tests/cases/conformance/types/spread/objectSpreadNegative.ts(80,14): error TS2698: Spread types may only be created from object types.
==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (24 errors) ====
==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (17 errors) ====
let o = { a: 1, b: 'no' }
/// private propagates
@ -66,8 +59,6 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(80,14): error TS269
!!! error TS2322: Property 's' is missing in type '{ b: boolean; }'.
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
~~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
~
!!! error TS2300: Duplicate identifier 'b'.
~
@ -76,31 +67,19 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(80,14): error TS269
// Note: ignore changes the order that properties are printed
let ignore: { a: number, b: string } =
{ b: 'ignored', ...o }
~~~~~~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
let o3 = { a: 1, b: 'no' }
let o4 = { b: 'yes', c: true }
let combinedBefore: { a: number, b: string, c: boolean } =
{ b: 'ok', ...o3, ...o4 }
~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
let combinedMid: { a: number, b: string, c: boolean } =
{ ...o3, b: 'ok', ...o4 }
~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
let combinedNested: { a: number, b: boolean, c: string, d: string } =
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
~~~~~~~~~~~~~~~~~
!!! error TS2735: 'd' is overwritten by a later spread.
let changeTypeBefore: { a: number, b: string } =
{ a: 'wrong type?', ...o3 };
~~~~~~~~~~~~~~~~
!!! error TS2735: 'a' is overwritten by a later spread.
let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } =
{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
~~~~~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
// primitives are not allowed, except for falsy ones
let spreadNum = { ...12 };

View file

@ -1,12 +0,0 @@
tests/cases/conformance/types/spread/spreadOverwritesProperty.ts(3,17): error TS2735: 'b' is overwritten by a later spread.
==== tests/cases/conformance/types/spread/spreadOverwritesProperty.ts (1 errors) ====
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }

View file

@ -4,6 +4,13 @@ declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
function g(obj: { x: number | undefined }) {
return { x: 1, ...obj }; // should be allowed because of undefined
}
function h(obj: { x: number }) {
return { x: 1, ...obj }; // should be allowed because we don't know about undefined
}
//// [spreadOverwritesProperty.js]
@ -21,3 +28,9 @@ var __assign = (this && this.__assign) || function () {
var unused1 = __assign({ b: 1 }, ab);
var unused2 = __assign({}, ab, ab);
var unused3 = __assign({ b: 1 }, abq);
function g(obj) {
return __assign({ x: 1 }, obj); // should be allowed because of undefined
}
function h(obj) {
return __assign({ x: 1 }, obj); // should be allowed because we don't know about undefined
}

View file

@ -24,3 +24,22 @@ var unused3 = { b: 1, ...abq }
>b : Symbol(b, Decl(spreadOverwritesProperty.ts, 4, 15))
>abq : Symbol(abq, Decl(spreadOverwritesProperty.ts, 1, 11))
function g(obj: { x: number | undefined }) {
>g : Symbol(g, Decl(spreadOverwritesProperty.ts, 4, 30))
>obj : Symbol(obj, Decl(spreadOverwritesProperty.ts, 6, 11))
>x : Symbol(x, Decl(spreadOverwritesProperty.ts, 6, 17))
return { x: 1, ...obj }; // should be allowed because of undefined
>x : Symbol(x, Decl(spreadOverwritesProperty.ts, 7, 12))
>obj : Symbol(obj, Decl(spreadOverwritesProperty.ts, 6, 11))
}
function h(obj: { x: number }) {
>h : Symbol(h, Decl(spreadOverwritesProperty.ts, 8, 1))
>obj : Symbol(obj, Decl(spreadOverwritesProperty.ts, 9, 11))
>x : Symbol(x, Decl(spreadOverwritesProperty.ts, 9, 17))
return { x: 1, ...obj }; // should be allowed because we don't know about undefined
>x : Symbol(x, Decl(spreadOverwritesProperty.ts, 10, 12))
>obj : Symbol(obj, Decl(spreadOverwritesProperty.ts, 9, 11))
}

View file

@ -29,3 +29,26 @@ var unused3 = { b: 1, ...abq }
>1 : 1
>abq : { a: number; b?: number; }
function g(obj: { x: number | undefined }) {
>g : (obj: { x: number; }) => { x: number; }
>obj : { x: number; }
>x : number
return { x: 1, ...obj }; // should be allowed because of undefined
>{ x: 1, ...obj } : { x: number; }
>x : number
>1 : 1
>obj : { x: number; }
}
function h(obj: { x: number }) {
>h : (obj: { x: number; }) => { x: number; }
>obj : { x: number; }
>x : number
return { x: 1, ...obj }; // should be allowed because we don't know about undefined
>{ x: 1, ...obj } : { x: number; }
>x : number
>1 : 1
>obj : { x: number; }
}

View file

@ -9,4 +9,10 @@ tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(3,17): er
!!! error TS2735: 'b' is overwritten by a later spread.
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
function g(obj: { x: number | undefined }) {
return { x: 1, ...obj }; // should be allowed because of undefined
}
function f(obj: { x: number } | undefined) {
return { x: 1, ...obj };
}

View file

@ -4,6 +4,12 @@ declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
function g(obj: { x: number | undefined }) {
return { x: 1, ...obj }; // should be allowed because of undefined
}
function f(obj: { x: number } | undefined) {
return { x: 1, ...obj };
}
//// [spreadOverwritesPropertyStrict.js]
@ -22,3 +28,9 @@ var __assign = (this && this.__assign) || function () {
var unused1 = __assign({ b: 1 }, ab);
var unused2 = __assign({}, ab, ab);
var unused3 = __assign({ b: 1 }, abq);
function g(obj) {
return __assign({ x: 1 }, obj); // should be allowed because of undefined
}
function f(obj) {
return __assign({ x: 1 }, obj);
}

View file

@ -24,3 +24,22 @@ var unused3 = { b: 1, ...abq }
>b : Symbol(b, Decl(spreadOverwritesPropertyStrict.ts, 4, 15))
>abq : Symbol(abq, Decl(spreadOverwritesPropertyStrict.ts, 1, 11))
function g(obj: { x: number | undefined }) {
>g : Symbol(g, Decl(spreadOverwritesPropertyStrict.ts, 4, 30))
>obj : Symbol(obj, Decl(spreadOverwritesPropertyStrict.ts, 5, 11))
>x : Symbol(x, Decl(spreadOverwritesPropertyStrict.ts, 5, 17))
return { x: 1, ...obj }; // should be allowed because of undefined
>x : Symbol(x, Decl(spreadOverwritesPropertyStrict.ts, 6, 12))
>obj : Symbol(obj, Decl(spreadOverwritesPropertyStrict.ts, 5, 11))
}
function f(obj: { x: number } | undefined) {
>f : Symbol(f, Decl(spreadOverwritesPropertyStrict.ts, 7, 1))
>obj : Symbol(obj, Decl(spreadOverwritesPropertyStrict.ts, 8, 11))
>x : Symbol(x, Decl(spreadOverwritesPropertyStrict.ts, 8, 17))
return { x: 1, ...obj };
>x : Symbol(x, Decl(spreadOverwritesPropertyStrict.ts, 9, 12))
>obj : Symbol(obj, Decl(spreadOverwritesPropertyStrict.ts, 8, 11))
}

View file

@ -29,3 +29,26 @@ var unused3 = { b: 1, ...abq }
>1 : 1
>abq : { a: number; b?: number | undefined; }
function g(obj: { x: number | undefined }) {
>g : (obj: { x: number | undefined; }) => { x: number | undefined; }
>obj : { x: number | undefined; }
>x : number | undefined
return { x: 1, ...obj }; // should be allowed because of undefined
>{ x: 1, ...obj } : { x: number | undefined; }
>x : number
>1 : 1
>obj : { x: number | undefined; }
}
function f(obj: { x: number } | undefined) {
>f : (obj: { x: number; } | undefined) => { x: number; } | { x: number; }
>obj : { x: number; } | undefined
>x : number
return { x: 1, ...obj };
>{ x: 1, ...obj } : { x: number; } | { x: number; }
>x : number
>1 : 1
>obj : { x: number; } | undefined
}

View file

@ -1,18 +1,15 @@
tests/cases/conformance/types/spread/spreadUnion3.ts(2,14): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/spread/spreadUnion3.ts(2,14): error TS2735: 'y' is overwritten by a later spread.
tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Property 'a' does not exist on type '{}'.
tests/cases/conformance/types/spread/spreadUnion3.ts(17,11): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/spreadUnion3.ts(18,11): error TS2698: Spread types may only be created from object types.
==== tests/cases/conformance/types/spread/spreadUnion3.ts (5 errors) ====
==== tests/cases/conformance/types/spread/spreadUnion3.ts (4 errors) ====
function f(x: { y: string } | undefined): { y: string } {
return { y: 123, ...x } // y: string | number
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6500 tests/cases/conformance/types/spread/spreadUnion3.ts:1:45: The expected type comes from property 'y' which is declared here on type '{ y: string; }'
~~~~~~
!!! error TS2735: 'y' is overwritten by a later spread.
}
f(undefined)

View file

@ -3,3 +3,10 @@ declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
function g(obj: { x: number | undefined }) {
return { x: 1, ...obj }; // should be allowed because of undefined
}
function h(obj: { x: number }) {
return { x: 1, ...obj }; // should be allowed because we don't know about undefined
}

View file

@ -4,3 +4,9 @@ declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
function g(obj: { x: number | undefined }) {
return { x: 1, ...obj }; // should be allowed because of undefined
}
function f(obj: { x: number } | undefined) {
return { x: 1, ...obj };
}