diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 05e0ab3fd2d..580d2a1aee2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6906,6 +6906,8 @@ namespace ts { containsString?: boolean; containsNumber?: boolean; containsStringOrNumberLiteral?: boolean; + containsObjectType?: boolean; + containsEmptyObject?: boolean; unionIndex?: number; } @@ -7101,7 +7103,13 @@ namespace ts { else if (type.flags & TypeFlags.Any) { typeSet.containsAny = true; } + else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) { + typeSet.containsEmptyObject = true; + } else if (!(type.flags & TypeFlags.Never) && (strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { + if (type.flags & TypeFlags.Object) { + typeSet.containsObjectType = true; + } if (type.flags & TypeFlags.Union && typeSet.unionIndex === undefined) { typeSet.unionIndex = typeSet.length; } @@ -7139,6 +7147,9 @@ namespace ts { if (typeSet.containsAny) { return anyType; } + if (typeSet.containsEmptyObject && !typeSet.containsObjectType) { + typeSet.push(emptyObjectType); + } if (typeSet.length === 1) { return typeSet[0]; } @@ -8309,6 +8320,18 @@ namespace ts { } } + function isEmptyResolvedType(t: ResolvedType) { + return t.properties.length === 0 && + t.callSignatures.length === 0 && + t.constructSignatures.length === 0 && + !t.stringIndexInfo && + !t.numberIndexInfo; + } + + function isEmptyObjectType(type: Type) { + return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(type)); + } + function isEnumTypeRelatedTo(source: EnumType, target: EnumType, errorReporter?: ErrorReporter) { if (source === target) { return true; @@ -8644,18 +8667,6 @@ namespace ts { return false; } - function isEmptyResolvedType(t: ResolvedType) { - return t.properties.length === 0 && - t.callSignatures.length === 0 && - t.constructSignatures.length === 0 && - !t.stringIndexInfo && - !t.numberIndexInfo; - } - - function isEmptyObjectType(type: Type) { - return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(type)); - } - function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes); diff --git a/tests/baselines/reference/declarationEmitPromise.js b/tests/baselines/reference/declarationEmitPromise.js index 5ed52f8af4c..6822dc56c3d 100644 --- a/tests/baselines/reference/declarationEmitPromise.js +++ b/tests/baselines/reference/declarationEmitPromise.js @@ -59,5 +59,5 @@ exports.runSampleBreaks = runSampleBreaks; export declare class bluebird { static all: Array>; } -export declare function runSampleWorks(a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird): Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}>; +export declare function runSampleWorks(a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird): Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>; export declare function runSampleBreaks(a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird): Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>; diff --git a/tests/baselines/reference/declarationEmitPromise.types b/tests/baselines/reference/declarationEmitPromise.types index 12323398a18..70012094bf3 100644 --- a/tests/baselines/reference/declarationEmitPromise.types +++ b/tests/baselines/reference/declarationEmitPromise.types @@ -10,7 +10,7 @@ export class bluebird { } export async function runSampleWorks( ->runSampleWorks : (a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) => Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}> +>runSampleWorks : (a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) => Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)> >A : A >B : B >C : C @@ -85,13 +85,13 @@ export async function runSampleWorks( >result : any let rfunc: typeof func & {} = func as any; // <- This is the only difference ->rfunc : ((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {} +>rfunc : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T >func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T >func as any : any >func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T return rfunc ->rfunc : ((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {} +>rfunc : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T } export async function runSampleBreaks( diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types index cd6c2d58e4a..ef97847cc73 100644 --- a/tests/baselines/reference/genericDefaults.types +++ b/tests/baselines/reference/genericDefaults.types @@ -1094,7 +1094,7 @@ declare function f12(a?: T, b?: U): [T, U]; // inference f12(); ->f12() : [{}, {} & B] +>f12() : [{}, B] >f12 : (a?: T, b?: U) => [T, U] f12(a); @@ -1856,7 +1856,7 @@ declare function f19(a?: T, b?: U): [T, U]; // inference f19(); ->f19() : [{}, {} & B] +>f19() : [{}, B] >f19 : (a?: T, b?: U) => [T, U] f19(a); @@ -1950,11 +1950,11 @@ declare function f20(a?: T, b?: U, c?: V): [T, U, V]; // inference f20(); ->f20() : [{}, {}, {} & C] +>f20() : [{}, {}, C] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] f20(a); ->f20(a) : [A, {}, {} & C] +>f20(a) : [A, {}, C] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >a : A @@ -1973,25 +1973,25 @@ f20(a, b, c); // no inference, partially supplied f20(); ->f20() : [A, {}, {} & C] +>f20() : [A, {}, C] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >A : A f20(a); ->f20(a) : [A, {}, {} & C] +>f20(a) : [A, {}, C] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >A : A >a : A f20(a, b); ->f20(a, b) : [A, {}, {} & C] +>f20(a, b) : [A, {}, C] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >A : A >a : A >b : B f20(a, b, bc); ->f20(a, b, bc) : [A, {}, {} & C] +>f20(a, b, bc) : [A, {}, C] >f20 : (a?: T, b?: U, c?: V) => [T, U, V] >A : A >a : A diff --git a/tests/baselines/reference/intersectionsAndEmptyObjects.js b/tests/baselines/reference/intersectionsAndEmptyObjects.js new file mode 100644 index 00000000000..1ac9606c3a9 --- /dev/null +++ b/tests/baselines/reference/intersectionsAndEmptyObjects.js @@ -0,0 +1,45 @@ +//// [intersectionsAndEmptyObjects.ts] +// Empty object type literals are removed from intersections types +// that contain other object types + +type A = { a: number }; +type B = { b: string }; +type C = {}; + +let x01: A & B; +let x02: A & C; +let x03: B & C; +let x04: A & B & C; +let x05: string & C; +let x06: C & string; +let x07: C; +let x08: C & {}; +let x09: {} & A & {} & B & {} & C & {}; + +interface D {} +interface E {} + +let x10: A & D; +let x11: C & D; +let x12: A & B & C & D; +let x13: D & E; +let x14: A & B & C & D & E; + + +//// [intersectionsAndEmptyObjects.js] +// Empty object type literals are removed from intersections types +// that contain other object types +var x01; +var x02; +var x03; +var x04; +var x05; +var x06; +var x07; +var x08; +var x09; +var x10; +var x11; +var x12; +var x13; +var x14; diff --git a/tests/baselines/reference/intersectionsAndEmptyObjects.symbols b/tests/baselines/reference/intersectionsAndEmptyObjects.symbols new file mode 100644 index 00000000000..14189a1c10b --- /dev/null +++ b/tests/baselines/reference/intersectionsAndEmptyObjects.symbols @@ -0,0 +1,94 @@ +=== tests/cases/conformance/types/intersection/intersectionsAndEmptyObjects.ts === +// Empty object type literals are removed from intersections types +// that contain other object types + +type A = { a: number }; +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>a : Symbol(a, Decl(intersectionsAndEmptyObjects.ts, 3, 10)) + +type B = { b: string }; +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) +>b : Symbol(b, Decl(intersectionsAndEmptyObjects.ts, 4, 10)) + +type C = {}; +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x01: A & B; +>x01 : Symbol(x01, Decl(intersectionsAndEmptyObjects.ts, 7, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) + +let x02: A & C; +>x02 : Symbol(x02, Decl(intersectionsAndEmptyObjects.ts, 8, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x03: B & C; +>x03 : Symbol(x03, Decl(intersectionsAndEmptyObjects.ts, 9, 3)) +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x04: A & B & C; +>x04 : Symbol(x04, Decl(intersectionsAndEmptyObjects.ts, 10, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x05: string & C; +>x05 : Symbol(x05, Decl(intersectionsAndEmptyObjects.ts, 11, 3)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x06: C & string; +>x06 : Symbol(x06, Decl(intersectionsAndEmptyObjects.ts, 12, 3)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x07: C; +>x07 : Symbol(x07, Decl(intersectionsAndEmptyObjects.ts, 13, 3)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x08: C & {}; +>x08 : Symbol(x08, Decl(intersectionsAndEmptyObjects.ts, 14, 3)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +let x09: {} & A & {} & B & {} & C & {}; +>x09 : Symbol(x09, Decl(intersectionsAndEmptyObjects.ts, 15, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) + +interface D {} +>D : Symbol(D, Decl(intersectionsAndEmptyObjects.ts, 15, 39)) + +interface E {} +>E : Symbol(E, Decl(intersectionsAndEmptyObjects.ts, 17, 14)) + +let x10: A & D; +>x10 : Symbol(x10, Decl(intersectionsAndEmptyObjects.ts, 20, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>D : Symbol(D, Decl(intersectionsAndEmptyObjects.ts, 15, 39)) + +let x11: C & D; +>x11 : Symbol(x11, Decl(intersectionsAndEmptyObjects.ts, 21, 3)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) +>D : Symbol(D, Decl(intersectionsAndEmptyObjects.ts, 15, 39)) + +let x12: A & B & C & D; +>x12 : Symbol(x12, Decl(intersectionsAndEmptyObjects.ts, 22, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) +>D : Symbol(D, Decl(intersectionsAndEmptyObjects.ts, 15, 39)) + +let x13: D & E; +>x13 : Symbol(x13, Decl(intersectionsAndEmptyObjects.ts, 23, 3)) +>D : Symbol(D, Decl(intersectionsAndEmptyObjects.ts, 15, 39)) +>E : Symbol(E, Decl(intersectionsAndEmptyObjects.ts, 17, 14)) + +let x14: A & B & C & D & E; +>x14 : Symbol(x14, Decl(intersectionsAndEmptyObjects.ts, 24, 3)) +>A : Symbol(A, Decl(intersectionsAndEmptyObjects.ts, 0, 0)) +>B : Symbol(B, Decl(intersectionsAndEmptyObjects.ts, 3, 23)) +>C : Symbol(C, Decl(intersectionsAndEmptyObjects.ts, 4, 23)) +>D : Symbol(D, Decl(intersectionsAndEmptyObjects.ts, 15, 39)) +>E : Symbol(E, Decl(intersectionsAndEmptyObjects.ts, 17, 14)) + diff --git a/tests/baselines/reference/intersectionsAndEmptyObjects.types b/tests/baselines/reference/intersectionsAndEmptyObjects.types new file mode 100644 index 00000000000..b3db1764e3c --- /dev/null +++ b/tests/baselines/reference/intersectionsAndEmptyObjects.types @@ -0,0 +1,94 @@ +=== tests/cases/conformance/types/intersection/intersectionsAndEmptyObjects.ts === +// Empty object type literals are removed from intersections types +// that contain other object types + +type A = { a: number }; +>A : A +>a : number + +type B = { b: string }; +>B : B +>b : string + +type C = {}; +>C : C + +let x01: A & B; +>x01 : A & B +>A : A +>B : B + +let x02: A & C; +>x02 : A +>A : A +>C : C + +let x03: B & C; +>x03 : B +>B : B +>C : C + +let x04: A & B & C; +>x04 : A & B +>A : A +>B : B +>C : C + +let x05: string & C; +>x05 : string & {} +>C : C + +let x06: C & string; +>x06 : string & {} +>C : C + +let x07: C; +>x07 : C +>C : C + +let x08: C & {}; +>x08 : {} +>C : C + +let x09: {} & A & {} & B & {} & C & {}; +>x09 : A & B +>A : A +>B : B +>C : C + +interface D {} +>D : D + +interface E {} +>E : E + +let x10: A & D; +>x10 : A & D +>A : A +>D : D + +let x11: C & D; +>x11 : D +>C : C +>D : D + +let x12: A & B & C & D; +>x12 : A & B & D +>A : A +>B : B +>C : C +>D : D + +let x13: D & E; +>x13 : D & E +>D : D +>E : E + +let x14: A & B & C & D & E; +>x14 : A & B & D & E +>A : A +>B : B +>C : C +>D : D +>E : E + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index c1200fc6bd4..19ecac10188 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1866,9 +1866,9 @@ let c1 = new Component1({ c1.get("hello"); >c1.get("hello") : string ->c1.get : (key: K) => ({ hello: string; } & {})[K] +>c1.get : (key: K) => { hello: string; }[K] >c1 : Component1<{ hello: string; }, {}> ->get : (key: K) => ({ hello: string; } & {})[K] +>get : (key: K) => { hello: string; }[K] >"hello" : "hello" // Repro from #12625 diff --git a/tests/baselines/reference/tsxAttributeResolution15.errors.txt b/tests/baselines/reference/tsxAttributeResolution15.errors.txt index 7af62ac2b79..870599acd27 100644 --- a/tests/baselines/reference/tsxAttributeResolution15.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution15.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(11,21): error TS2322: Type '{ prop1: "hello"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. - Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(11,21): error TS2322: Type '{ prop1: "hello"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. + Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -15,8 +15,8 @@ tests/cases/conformance/jsx/file.tsx(11,21): error TS2322: Type '{ prop1: "hello // Error let a = ~~~~~~~~~~~~~ -!!! error TS2322: Type '{ prop1: "hello"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. +!!! error TS2322: Type '{ prop1: "hello"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. // OK let b = { this.textInput = input; }} /> diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt index b4b458962ff..2212d0da025 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt @@ -2,8 +2,8 @@ tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ x: string; y: Type '{ x: string; y: number; }' is not assignable to type 'PoisonedProp'. Types of property 'y' are incompatible. Type 'number' is not assignable to type '2'. -tests/cases/conformance/jsx/file.tsx(33,20): error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. - Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(33,20): error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. + Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. ==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== @@ -46,5 +46,5 @@ tests/cases/conformance/jsx/file.tsx(33,20): error TS2322: Type '{ prop1: boolea // Error let e = ; ~~~~~~ -!!! error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. \ No newline at end of file +!!! error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt index cbbab2910ff..51e1de2a57e 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt @@ -9,13 +9,13 @@ tests/cases/conformance/jsx/file.tsx(29,15): error TS2322: Type '{ naaaaaaame: " tests/cases/conformance/jsx/file.tsx(34,23): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { "prop-name": string; }'. Type '{}' is not assignable to type '{ "prop-name": string; }'. Property '"prop-name"' is missing in type '{}'. -tests/cases/conformance/jsx/file.tsx(37,23): error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes & {}'. - Property 'prop1' does not exist on type 'IntrinsicAttributes & {}'. -tests/cases/conformance/jsx/file.tsx(38,24): error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes & {}'. - Property 'ref' does not exist on type 'IntrinsicAttributes & {}'. +tests/cases/conformance/jsx/file.tsx(37,23): error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. + Property 'prop1' does not exist on type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(38,24): error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. + Property 'ref' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(41,16): error TS1005: ',' expected. -tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & {}'. - Property 'prop1' does not exist on type 'IntrinsicAttributes & {}'. +tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes'. + Property 'prop1' does not exist on type 'IntrinsicAttributes'. ==== tests/cases/conformance/jsx/file.tsx (8 errors) ==== @@ -72,12 +72,12 @@ tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolea // Error let i = ~~~~~ -!!! error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes & {}'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & {}'. +!!! error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. +!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'. let i1 = x.greeting.substr(10)} /> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes & {}'. -!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes & {}'. +!!! error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. +!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes'. let o = { prop1: true; @@ -88,8 +88,8 @@ tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolea // Error let i2 = ~~~~~~ -!!! error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & {}'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & {}'. +!!! error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes'. +!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'. let o1: any; // OK diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index 5b7355ba172..7c94a08b6ef 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -3,10 +3,10 @@ tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type '{ x: true; }' i Type '{ x: true; }' is not assignable to type '{ x: string; }'. Types of property 'x' are incompatible. Type 'true' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(33,21): error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. - Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. -tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. - Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(33,21): error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. + Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. + Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. ==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== @@ -50,10 +50,10 @@ tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; } !!! error TS2322: Type 'true' is not assignable to type 'string'. let b = ~~~~~~ -!!! error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. -!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. let c = ; ~~~~ -!!! error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. -!!! error TS2322: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'. +!!! error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2322: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxUnionElementType6.errors.txt b/tests/baselines/reference/tsxUnionElementType6.errors.txt index 0a36d3f4bc5..1f31fb21f26 100644 --- a/tests/baselines/reference/tsxUnionElementType6.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType6.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(18,23): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & {}'. - Property 'x' does not exist on type 'IntrinsicAttributes & {}'. +tests/cases/conformance/jsx/file.tsx(18,23): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. + Property 'x' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(19,27): error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'. Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'. Types of property 'x' are incompatible. @@ -32,8 +32,8 @@ tests/cases/conformance/jsx/file.tsx(21,27): error TS2322: Type '{}' is not assi // Error let a = ; ~ -!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & {}'. -!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & {}'. +!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. +!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes'. let b = ; ~~~~~~ !!! error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'. diff --git a/tests/cases/conformance/types/intersection/intersectionsAndEmptyObjects.ts b/tests/cases/conformance/types/intersection/intersectionsAndEmptyObjects.ts new file mode 100644 index 00000000000..86ff93281c0 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionsAndEmptyObjects.ts @@ -0,0 +1,25 @@ +// Empty object type literals are removed from intersections types +// that contain other object types + +type A = { a: number }; +type B = { b: string }; +type C = {}; + +let x01: A & B; +let x02: A & C; +let x03: B & C; +let x04: A & B & C; +let x05: string & C; +let x06: C & string; +let x07: C; +let x08: C & {}; +let x09: {} & A & {} & B & {} & C & {}; + +interface D {} +interface E {} + +let x10: A & D; +let x11: C & D; +let x12: A & B & C & D; +let x13: D & E; +let x14: A & B & C & D & E;