From 54fa9507574595d6c1331fa176ba6be913524c52 Mon Sep 17 00:00:00 2001 From: Andrii Dieiev Date: Tue, 23 Apr 2019 23:49:32 +0300 Subject: [PATCH] Skip primitive types comparison with array and object types (#31077) --- src/compiler/checker.ts | 2 + .../assignmentIndexedToPrimitives.errors.txt | 55 +++++++++++++++ .../assignmentIndexedToPrimitives.js | 31 +++++++++ .../assignmentIndexedToPrimitives.symbols | 41 +++++++++++ .../assignmentIndexedToPrimitives.types | 68 +++++++++++++++++++ tests/baselines/reference/for-of10.errors.txt | 4 +- tests/baselines/reference/for-of11.errors.txt | 8 ++- ...wrappedAndRecursiveConstraints4.errors.txt | 8 +-- .../compiler/assignmentIndexedToPrimitives.ts | 15 ++++ 9 files changed, 222 insertions(+), 10 deletions(-) create mode 100644 tests/baselines/reference/assignmentIndexedToPrimitives.errors.txt create mode 100644 tests/baselines/reference/assignmentIndexedToPrimitives.js create mode 100644 tests/baselines/reference/assignmentIndexedToPrimitives.symbols create mode 100644 tests/baselines/reference/assignmentIndexedToPrimitives.types create mode 100644 tests/cases/compiler/assignmentIndexedToPrimitives.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index df3f9fc624f..2652318f959 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11859,6 +11859,7 @@ namespace ts { } function elaborateArrayLiteral(node: ArrayLiteralExpression, source: Type, target: Type, relation: Map) { + if (target.flags & TypeFlags.Primitive) return false; if (isTupleLikeType(source)) { return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation); } @@ -11895,6 +11896,7 @@ namespace ts { } function elaborateObjectLiteral(node: ObjectLiteralExpression, source: Type, target: Type, relation: Map) { + if (target.flags & TypeFlags.Primitive) return false; return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation); } diff --git a/tests/baselines/reference/assignmentIndexedToPrimitives.errors.txt b/tests/baselines/reference/assignmentIndexedToPrimitives.errors.txt new file mode 100644 index 00000000000..88c822f6dcb --- /dev/null +++ b/tests/baselines/reference/assignmentIndexedToPrimitives.errors.txt @@ -0,0 +1,55 @@ +tests/cases/compiler/assignmentIndexedToPrimitives.ts(1,7): error TS2322: Type 'number[]' is not assignable to type 'number'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(2,7): error TS2322: Type 'string[]' is not assignable to type 'number'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(3,7): error TS2322: Type '(string | number)[]' is not assignable to type 'number'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(4,7): error TS2322: Type 'number[]' is not assignable to type '0'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(6,7): error TS2322: Type 'number[]' is not assignable to type 'string'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(7,7): error TS2322: Type 'string[]' is not assignable to type 'string'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(8,7): error TS2322: Type '(string | number)[]' is not assignable to type 'string'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(9,7): error TS2322: Type 'string[]' is not assignable to type '"01"'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(11,7): error TS2322: Type '{ 0: number; }' is not assignable to type 'number'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(13,7): error TS2322: Type '{ 0: number; }' is not assignable to type 'string'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(14,7): error TS2322: Type '{ "0": number; }' is not assignable to type 'string'. +tests/cases/compiler/assignmentIndexedToPrimitives.ts(15,7): error TS2322: Type '{ 0: string; }' is not assignable to type 'string'. + + +==== tests/cases/compiler/assignmentIndexedToPrimitives.ts (12 errors) ==== + const n1: number = [0]; + ~~ +!!! error TS2322: Type 'number[]' is not assignable to type 'number'. + const n2: number = ["0"]; + ~~ +!!! error TS2322: Type 'string[]' is not assignable to type 'number'. + const n3: number = [0, "1"]; + ~~ +!!! error TS2322: Type '(string | number)[]' is not assignable to type 'number'. + const n4: 0 = [0]; + ~~ +!!! error TS2322: Type 'number[]' is not assignable to type '0'. + + const s1: string = [0]; + ~~ +!!! error TS2322: Type 'number[]' is not assignable to type 'string'. + const s2: string = ["0"]; + ~~ +!!! error TS2322: Type 'string[]' is not assignable to type 'string'. + const s3: string = [0, "1"]; + ~~ +!!! error TS2322: Type '(string | number)[]' is not assignable to type 'string'. + const s4: "01" = ["0", "1"]; + ~~ +!!! error TS2322: Type 'string[]' is not assignable to type '"01"'. + + const no1: number = { 0: 1 }; + ~~~ +!!! error TS2322: Type '{ 0: number; }' is not assignable to type 'number'. + + const so1: string = { 0: 1 }; + ~~~ +!!! error TS2322: Type '{ 0: number; }' is not assignable to type 'string'. + const so2: string = { "0": 1 }; + ~~~ +!!! error TS2322: Type '{ "0": number; }' is not assignable to type 'string'. + const so3: string = { 0: "1" }; + ~~~ +!!! error TS2322: Type '{ 0: string; }' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentIndexedToPrimitives.js b/tests/baselines/reference/assignmentIndexedToPrimitives.js new file mode 100644 index 00000000000..363d41fc14d --- /dev/null +++ b/tests/baselines/reference/assignmentIndexedToPrimitives.js @@ -0,0 +1,31 @@ +//// [assignmentIndexedToPrimitives.ts] +const n1: number = [0]; +const n2: number = ["0"]; +const n3: number = [0, "1"]; +const n4: 0 = [0]; + +const s1: string = [0]; +const s2: string = ["0"]; +const s3: string = [0, "1"]; +const s4: "01" = ["0", "1"]; + +const no1: number = { 0: 1 }; + +const so1: string = { 0: 1 }; +const so2: string = { "0": 1 }; +const so3: string = { 0: "1" }; + + +//// [assignmentIndexedToPrimitives.js] +var n1 = [0]; +var n2 = ["0"]; +var n3 = [0, "1"]; +var n4 = [0]; +var s1 = [0]; +var s2 = ["0"]; +var s3 = [0, "1"]; +var s4 = ["0", "1"]; +var no1 = { 0: 1 }; +var so1 = { 0: 1 }; +var so2 = { "0": 1 }; +var so3 = { 0: "1" }; diff --git a/tests/baselines/reference/assignmentIndexedToPrimitives.symbols b/tests/baselines/reference/assignmentIndexedToPrimitives.symbols new file mode 100644 index 00000000000..37b41d2f9c9 --- /dev/null +++ b/tests/baselines/reference/assignmentIndexedToPrimitives.symbols @@ -0,0 +1,41 @@ +=== tests/cases/compiler/assignmentIndexedToPrimitives.ts === +const n1: number = [0]; +>n1 : Symbol(n1, Decl(assignmentIndexedToPrimitives.ts, 0, 5)) + +const n2: number = ["0"]; +>n2 : Symbol(n2, Decl(assignmentIndexedToPrimitives.ts, 1, 5)) + +const n3: number = [0, "1"]; +>n3 : Symbol(n3, Decl(assignmentIndexedToPrimitives.ts, 2, 5)) + +const n4: 0 = [0]; +>n4 : Symbol(n4, Decl(assignmentIndexedToPrimitives.ts, 3, 5)) + +const s1: string = [0]; +>s1 : Symbol(s1, Decl(assignmentIndexedToPrimitives.ts, 5, 5)) + +const s2: string = ["0"]; +>s2 : Symbol(s2, Decl(assignmentIndexedToPrimitives.ts, 6, 5)) + +const s3: string = [0, "1"]; +>s3 : Symbol(s3, Decl(assignmentIndexedToPrimitives.ts, 7, 5)) + +const s4: "01" = ["0", "1"]; +>s4 : Symbol(s4, Decl(assignmentIndexedToPrimitives.ts, 8, 5)) + +const no1: number = { 0: 1 }; +>no1 : Symbol(no1, Decl(assignmentIndexedToPrimitives.ts, 10, 5)) +>0 : Symbol(0, Decl(assignmentIndexedToPrimitives.ts, 10, 21)) + +const so1: string = { 0: 1 }; +>so1 : Symbol(so1, Decl(assignmentIndexedToPrimitives.ts, 12, 5)) +>0 : Symbol(0, Decl(assignmentIndexedToPrimitives.ts, 12, 21)) + +const so2: string = { "0": 1 }; +>so2 : Symbol(so2, Decl(assignmentIndexedToPrimitives.ts, 13, 5)) +>"0" : Symbol("0", Decl(assignmentIndexedToPrimitives.ts, 13, 21)) + +const so3: string = { 0: "1" }; +>so3 : Symbol(so3, Decl(assignmentIndexedToPrimitives.ts, 14, 5)) +>0 : Symbol(0, Decl(assignmentIndexedToPrimitives.ts, 14, 21)) + diff --git a/tests/baselines/reference/assignmentIndexedToPrimitives.types b/tests/baselines/reference/assignmentIndexedToPrimitives.types new file mode 100644 index 00000000000..7c36c89b1e9 --- /dev/null +++ b/tests/baselines/reference/assignmentIndexedToPrimitives.types @@ -0,0 +1,68 @@ +=== tests/cases/compiler/assignmentIndexedToPrimitives.ts === +const n1: number = [0]; +>n1 : number +>[0] : number[] +>0 : 0 + +const n2: number = ["0"]; +>n2 : number +>["0"] : string[] +>"0" : "0" + +const n3: number = [0, "1"]; +>n3 : number +>[0, "1"] : (string | number)[] +>0 : 0 +>"1" : "1" + +const n4: 0 = [0]; +>n4 : 0 +>[0] : number[] +>0 : 0 + +const s1: string = [0]; +>s1 : string +>[0] : number[] +>0 : 0 + +const s2: string = ["0"]; +>s2 : string +>["0"] : string[] +>"0" : "0" + +const s3: string = [0, "1"]; +>s3 : string +>[0, "1"] : (string | number)[] +>0 : 0 +>"1" : "1" + +const s4: "01" = ["0", "1"]; +>s4 : "01" +>["0", "1"] : string[] +>"0" : "0" +>"1" : "1" + +const no1: number = { 0: 1 }; +>no1 : number +>{ 0: 1 } : { 0: number; } +>0 : number +>1 : 1 + +const so1: string = { 0: 1 }; +>so1 : string +>{ 0: 1 } : { 0: number; } +>0 : number +>1 : 1 + +const so2: string = { "0": 1 }; +>so2 : string +>{ "0": 1 } : { "0": number; } +>"0" : number +>1 : 1 + +const so3: string = { 0: "1" }; +>so3 : string +>{ 0: "1" } : { 0: string; } +>0 : string +>"1" : "1" + diff --git a/tests/baselines/reference/for-of10.errors.txt b/tests/baselines/reference/for-of10.errors.txt index 724b02dce69..1636f1a02d0 100644 --- a/tests/baselines/reference/for-of10.errors.txt +++ b/tests/baselines/reference/for-of10.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/es6/for-ofStatements/for-of10.ts(2,12): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/es6/for-ofStatements/for-of10.ts(2,6): error TS2322: Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/es6/for-ofStatements/for-of10.ts (1 errors) ==== var v: string; for (v of [0]) { } - ~ + ~ !!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/for-of11.errors.txt b/tests/baselines/reference/for-of11.errors.txt index 98721081433..dc527e73efe 100644 --- a/tests/baselines/reference/for-of11.errors.txt +++ b/tests/baselines/reference/for-of11.errors.txt @@ -1,8 +1,10 @@ -tests/cases/conformance/es6/for-ofStatements/for-of11.ts(2,12): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/es6/for-ofStatements/for-of11.ts(2,6): error TS2322: Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/es6/for-ofStatements/for-of11.ts (1 errors) ==== var v: string; for (v of [0, ""]) { } - ~ -!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file + ~ +!!! error TS2322: Type 'string | number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt b/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt index 4b19087eea0..47e8e6ff4f2 100644 --- a/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt +++ b/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints4.ts(13,25): error TS2322: Type '(x: number) => void' is not assignable to type '(pos: number) => string'. - Type 'void' is not assignable to type 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints4.ts(13,12): error TS2345: Argument of type '{ length: number; charAt: (x: number) => void; }' is not assignable to parameter of type 'string'. ==== tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints4.ts (1 errors) ==== @@ -16,6 +15,5 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursi var c = new C({ length: 2 }); var r = c.foo(''); var r2 = r({ length: 3, charAt: (x: number) => { '' } }); // error - ~~~~~~ -!!! error TS2322: Type '(x: number) => void' is not assignable to type '(pos: number) => string'. -!!! error TS2322: Type 'void' is not assignable to type 'string'. \ No newline at end of file + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ length: number; charAt: (x: number) => void; }' is not assignable to parameter of type 'string'. \ No newline at end of file diff --git a/tests/cases/compiler/assignmentIndexedToPrimitives.ts b/tests/cases/compiler/assignmentIndexedToPrimitives.ts new file mode 100644 index 00000000000..1a0fd5c604d --- /dev/null +++ b/tests/cases/compiler/assignmentIndexedToPrimitives.ts @@ -0,0 +1,15 @@ +const n1: number = [0]; +const n2: number = ["0"]; +const n3: number = [0, "1"]; +const n4: 0 = [0]; + +const s1: string = [0]; +const s2: string = ["0"]; +const s3: string = [0, "1"]; +const s4: "01" = ["0", "1"]; + +const no1: number = { 0: 1 }; + +const so1: string = { 0: 1 }; +const so2: string = { "0": 1 }; +const so3: string = { 0: "1" };