Test excess property checks of spreads of unions.

This commit is contained in:
Nathan Shively-Sanders 2017-10-17 09:56:28 -07:00
parent 08d7e182cd
commit e58aa10068
6 changed files with 83 additions and 1 deletions

View file

@ -96,4 +96,10 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(40,1): error TS2322: Type
// these two are not reported because there are two discriminant properties
over = { a: 1, b: 1, first: "ok", second: "error" }
over = { a: 1, b: 1, first: "ok", third: "error" }
// Freshness disappears after spreading a union
declare let t0: { a: any, b: any } | { d: any, e: any }
declare let t1: { a: any, b: any, c: any } | { c: any, d: any, e: any }
let t2 = { ...t1 }
t0 = t2

View file

@ -49,9 +49,24 @@ let over: Overlapping
// these two are not reported because there are two discriminant properties
over = { a: 1, b: 1, first: "ok", second: "error" }
over = { a: 1, b: 1, first: "ok", third: "error" }
// Freshness disappears after spreading a union
declare let t0: { a: any, b: any } | { d: any, e: any }
declare let t1: { a: any, b: any, c: any } | { c: any, d: any, e: any }
let t2 = { ...t1 }
t0 = t2
//// [excessPropertyCheckWithUnions.js]
"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var wrong = { tag: "T", a1: "extra" };
wrong = { tag: "A", d20: 12 };
wrong = { tag: "D" };
@ -72,3 +87,5 @@ var over;
// these two are not reported because there are two discriminant properties
over = { a: 1, b: 1, first: "ok", second: "error" };
over = { a: 1, b: 1, first: "ok", third: "error" };
var t2 = __assign({}, t1);
t0 = t2;

View file

@ -142,3 +142,28 @@ over = { a: 1, b: 1, first: "ok", third: "error" }
>first : Symbol(first, Decl(excessPropertyCheckWithUnions.ts, 49, 20))
>third : Symbol(third, Decl(excessPropertyCheckWithUnions.ts, 49, 33))
// Freshness disappears after spreading a union
declare let t0: { a: any, b: any } | { d: any, e: any }
>t0 : Symbol(t0, Decl(excessPropertyCheckWithUnions.ts, 52, 11))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 52, 17))
>b : Symbol(b, Decl(excessPropertyCheckWithUnions.ts, 52, 25))
>d : Symbol(d, Decl(excessPropertyCheckWithUnions.ts, 52, 38))
>e : Symbol(e, Decl(excessPropertyCheckWithUnions.ts, 52, 46))
declare let t1: { a: any, b: any, c: any } | { c: any, d: any, e: any }
>t1 : Symbol(t1, Decl(excessPropertyCheckWithUnions.ts, 53, 11))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 53, 17))
>b : Symbol(b, Decl(excessPropertyCheckWithUnions.ts, 53, 25))
>c : Symbol(c, Decl(excessPropertyCheckWithUnions.ts, 53, 33))
>c : Symbol(c, Decl(excessPropertyCheckWithUnions.ts, 53, 46))
>d : Symbol(d, Decl(excessPropertyCheckWithUnions.ts, 53, 54))
>e : Symbol(e, Decl(excessPropertyCheckWithUnions.ts, 53, 62))
let t2 = { ...t1 }
>t2 : Symbol(t2, Decl(excessPropertyCheckWithUnions.ts, 54, 3))
>t1 : Symbol(t1, Decl(excessPropertyCheckWithUnions.ts, 53, 11))
t0 = t2
>t0 : Symbol(t0, Decl(excessPropertyCheckWithUnions.ts, 52, 11))
>t2 : Symbol(t2, Decl(excessPropertyCheckWithUnions.ts, 54, 3))

View file

@ -194,3 +194,30 @@ over = { a: 1, b: 1, first: "ok", third: "error" }
>third : string
>"error" : "error"
// Freshness disappears after spreading a union
declare let t0: { a: any, b: any } | { d: any, e: any }
>t0 : { a: any; b: any; } | { d: any; e: any; }
>a : any
>b : any
>d : any
>e : any
declare let t1: { a: any, b: any, c: any } | { c: any, d: any, e: any }
>t1 : { a: any; b: any; c: any; } | { c: any; d: any; e: any; }
>a : any
>b : any
>c : any
>c : any
>d : any
>e : any
let t2 = { ...t1 }
>t2 : { a: any; b: any; c: any; } | { c: any; d: any; e: any; }
>{ ...t1 } : { a: any; b: any; c: any; } | { c: any; d: any; e: any; }
>t1 : { a: any; b: any; c: any; } | { c: any; d: any; e: any; }
t0 = t2
>t0 = t2 : { a: any; b: any; c: any; } | { c: any; d: any; e: any; }
>t0 : { a: any; b: any; } | { d: any; e: any; }
>t2 : { a: any; b: any; c: any; } | { c: any; d: any; e: any; }

View file

@ -89,7 +89,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
>p1 : T
var o2 = { ...p2 }; // OK
>o2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray<T>[]): T[]; concat(...items: (T | ReadonlyArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray<T>[]): T[]; concat(...items: (T | ReadonlyArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray<T>[]): T[]; concat(...items: (T | ReadonlyArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>p2 : T[]

View file

@ -1,3 +1,4 @@
// @strict: true
type ADT = {
tag: "A",
a1: string
@ -48,3 +49,9 @@ let over: Overlapping
// these two are not reported because there are two discriminant properties
over = { a: 1, b: 1, first: "ok", second: "error" }
over = { a: 1, b: 1, first: "ok", third: "error" }
// Freshness disappears after spreading a union
declare let t0: { a: any, b: any } | { d: any, e: any }
declare let t1: { a: any, b: any, c: any } | { c: any, d: any, e: any }
let t2 = { ...t1 }
t0 = t2