diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d7479b5d0b6..cb1d53714f4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15095,11 +15095,11 @@ namespace ts { } function isTypicalNondistributiveConditional(root: ConditionalRoot) { - return !root.isDistributive - && root.node.checkType.kind === SyntaxKind.TupleType - && length((root.node.checkType as TupleTypeNode).elements) === 1 - && root.node.extendsType.kind === SyntaxKind.TupleType - && length((root.node.extendsType as TupleTypeNode).elements) === 1; + return !root.isDistributive && isSingletonTupleType(root.node.checkType) && isSingletonTupleType(root.node.extendsType); + } + + function isSingletonTupleType(node: TypeNode) { + return isTupleTypeNode(node) && length(node.elements) === 1 && !isOptionalTypeNode(node.elements[0]) && !isRestTypeNode(node.elements[0]); } /** @@ -18711,7 +18711,7 @@ namespace ts { return Ternary.False; } if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source as TypeReference).target === (target as TypeReference).target && - !(getObjectFlags(source) & ObjectFlags.MarkerType || getObjectFlags(target) & ObjectFlags.MarkerType)) { + !isTupleType(source) && !(getObjectFlags(source) & ObjectFlags.MarkerType || getObjectFlags(target) & ObjectFlags.MarkerType)) { // We have type references to the same generic type, and the type references are not marker // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. @@ -19182,7 +19182,7 @@ namespace ts { removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); const related = isRelatedTo(sourceType, targetCheckType, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { - if (reportErrors) { + if (reportErrors && (targetArity > 1 || sourceArity > 1)) { if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) { reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourceIndex, i); } diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt index a19e0e1b438..1ce65087aec 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt +++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt @@ -21,7 +21,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error Type '2' is not assignable to type '1'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. - Type 'string' is not assignable to type 'number'. + Type at position 0 in source is not compatible with type at position 0 in target. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(31,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'. Types of property '0' are incompatible. Type 'string' is not assignable to type 'number'. @@ -97,7 +98,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error var n1: [number, string] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Type at position 0 in source is not compatible with type at position 0 in target. +!!! error TS2322: Type 'string' is not assignable to type 'number'. var n2: [number, string] = y; ~~ !!! error TS2322: Type 'StrNum' is not assignable to type '[number, string]'. diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index e062d433259..9df7953c0a2 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -7,9 +7,11 @@ tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Conver Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2493: Tuple type '[C, D, A]' of length '3' has no element at index '5'. tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. - Type 'string' is not comparable to type 'number'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'string' is not comparable to type 'number'. tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. - Property 'a' is missing in type 'C' but required in type 'A'. + Type at position 0 in source is not compatible with type at position 0 in target. + Property 'a' is missing in type 'C' but required in type 'A'. tests/cases/conformance/types/tuple/castingTuple.ts(32,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'. tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot find name 't4'. @@ -60,11 +62,13 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot var t3 = <[number, number]>numStrTuple; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. -!!! error TS2352: Type 'string' is not comparable to type 'number'. +!!! error TS2352: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2352: Type 'string' is not comparable to type 'number'. var t9 = <[A, I]>classCDTuple; ~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. -!!! error TS2352: Property 'a' is missing in type 'C' but required in type 'A'. +!!! error TS2352: Type at position 0 in source is not compatible with type at position 0 in target. +!!! error TS2352: Property 'a' is missing in type 'C' but required in type 'A'. !!! related TS2728 tests/cases/conformance/types/tuple/castingTuple.ts:2:11: 'a' is declared here. var array1 = numStrTuple; ~~~~~~ diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt index 4a248485a0e..809fbb1e584 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.errors.txt +++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt @@ -12,8 +12,9 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(23,1): error TS23 tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (8 errors) ==== @@ -65,5 +66,6 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23 numStrTuple = unionTuple3; ~~~~~~~~~~~ !!! error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. -!!! 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 +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! 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/iterableArrayPattern29.errors.txt b/tests/baselines/reference/iterableArrayPattern29.errors.txt index a978e357cdf..2c814e40e87 100644 --- a/tests/baselines/reference/iterableArrayPattern29.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern29.errors.txt @@ -1,5 +1,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(2,21): error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'. - Type 'boolean' is not assignable to type 'number'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'boolean' is not assignable to type 'number'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (1 errors) ==== @@ -7,4 +8,5 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(2,21): error takeFirstTwoEntries(...new Map([["", true], ["hello", true]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file +!!! error TS2345: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/restTupleElements1.errors.txt b/tests/baselines/reference/restTupleElements1.errors.txt index a09d7bebe72..c96ac5fb20c 100644 --- a/tests/baselines/reference/restTupleElements1.errors.txt +++ b/tests/baselines/reference/restTupleElements1.errors.txt @@ -11,9 +11,11 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(29,18): error TS2344: tests/cases/conformance/types/tuple/restTupleElements1.ts(30,18): error TS2344: Type '[number, ...number[]]' does not satisfy the constraint '[number]'. Target allows only 1 element(s) but source may have more. tests/cases/conformance/types/tuple/restTupleElements1.ts(32,31): error TS2344: Type '[number, ...string[]]' does not satisfy the constraint '[number, ...number[]]'. - Type 'string' is not assignable to type 'number'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(33,31): error TS2344: Type '[string, ...number[]]' does not satisfy the constraint '[number, ...number[]]'. - Type 'string' is not assignable to type 'number'. + Type at position 0 in source is not compatible with type at position 0 in target. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(34,31): error TS2344: Type '[number, number, string]' does not satisfy the constraint '[number, ...number[]]'. Type at positions 1 through 2 in source is not compatible with type at position 1 in target. Type 'string | number' is not assignable to type 'number'. @@ -81,11 +83,13 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A assign<[number, ...number[]], [number, ...string[]]>(); // Error ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, ...string[]]' does not satisfy the constraint '[number, ...number[]]'. -!!! error TS2344: Type 'string' is not assignable to type 'number'. +!!! error TS2344: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2344: Type 'string' is not assignable to type 'number'. assign<[number, ...number[]], [string, ...number[]]>(); // Error ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[string, ...number[]]' does not satisfy the constraint '[number, ...number[]]'. -!!! error TS2344: Type 'string' is not assignable to type 'number'. +!!! error TS2344: Type at position 0 in source is not compatible with type at position 0 in target. +!!! error TS2344: Type 'string' is not assignable to type 'number'. assign<[number, ...number[]], [number, number, string]>(); // Error ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, number, string]' does not satisfy the constraint '[number, ...number[]]'. diff --git a/tests/baselines/reference/strictOptionalProperties2.js b/tests/baselines/reference/strictOptionalProperties2.js new file mode 100644 index 00000000000..63079175a66 --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties2.js @@ -0,0 +1,19 @@ +//// [strictOptionalProperties2.ts] +// Repro from #44567 + +type T1 = { 0?: string | undefined } extends { 0?: string } ? true : false; // false +type T2 = [(string | undefined)?] extends [string?] ? true : false; // false + + +//// [strictOptionalProperties2.js] +"use strict"; +// Repro from #44567 + + +//// [strictOptionalProperties2.d.ts] +declare type T1 = { + 0?: string | undefined; +} extends { + 0?: string; +} ? true : false; +declare type T2 = [(string | undefined)?] extends [string?] ? true : false; diff --git a/tests/baselines/reference/strictOptionalProperties2.symbols b/tests/baselines/reference/strictOptionalProperties2.symbols new file mode 100644 index 00000000000..740befb877a --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties2.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/strictOptionalProperties2.ts === +// Repro from #44567 + +type T1 = { 0?: string | undefined } extends { 0?: string } ? true : false; // false +>T1 : Symbol(T1, Decl(strictOptionalProperties2.ts, 0, 0)) +>0 : Symbol(0, Decl(strictOptionalProperties2.ts, 2, 11)) +>0 : Symbol(0, Decl(strictOptionalProperties2.ts, 2, 46)) + +type T2 = [(string | undefined)?] extends [string?] ? true : false; // false +>T2 : Symbol(T2, Decl(strictOptionalProperties2.ts, 2, 75)) + diff --git a/tests/baselines/reference/strictOptionalProperties2.types b/tests/baselines/reference/strictOptionalProperties2.types new file mode 100644 index 00000000000..20f6dd290e6 --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties2.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/strictOptionalProperties2.ts === +// Repro from #44567 + +type T1 = { 0?: string | undefined } extends { 0?: string } ? true : false; // false +>T1 : false +>0 : string | undefined +>0 : string | undefined +>true : true +>false : false + +type T2 = [(string | undefined)?] extends [string?] ? true : false; // false +>T2 : false +>true : true +>false : false + diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index df0752ebee3..c819aabf005 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -18,9 +18,11 @@ tests/cases/compiler/tupleTypes.ts(49,1): error TS2322: Type '[number, {}]' is n Type 'number | {}' is not assignable to type 'number'. Type '{}' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(50,1): error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. - Type 'number' is not assignable to type 'string'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'number' is not assignable to type 'string'. tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. - Type '{}' is not assignable to type 'string'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type '{}' is not assignable to type 'string'. ==== tests/cases/compiler/tupleTypes.ts (14 errors) ==== @@ -109,11 +111,13 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n a1 = a2; // Error ~~ !!! error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'number' is not assignable to type 'string'. a1 = a3; // Error ~~ !!! error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. -!!! error TS2322: Type '{}' is not assignable to type 'string'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type '{}' is not assignable to type 'string'. a3 = a1; a3 = a2; \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 014493e637c..26e303faa69 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -9,8 +9,9 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(149,5): error TS2322: Typ tests/cases/conformance/types/tuple/variadicTuples1.ts(151,5): error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...U]'. Target requires 2 element(s) but source may have fewer. tests/cases/conformance/types/tuple/variadicTuples1.ts(152,5): error TS2322: Type '[string, ...T]' is not assignable to type '[string, ...U]'. - Type 'T' is not assignable to type 'U'. - 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'T' is not assignable to type 'U'. + 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(160,5): error TS2322: Type 'readonly [...T]' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'readonly [...T]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(162,5): error TS4104: The type 'readonly [...T]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. @@ -212,8 +213,9 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Typ z = y; // Error ~ !!! error TS2322: Type '[string, ...T]' is not assignable to type '[string, ...U]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. -!!! error TS2322: 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'. } // For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable diff --git a/tests/cases/compiler/strictOptionalProperties2.ts b/tests/cases/compiler/strictOptionalProperties2.ts new file mode 100644 index 00000000000..21d1959545d --- /dev/null +++ b/tests/cases/compiler/strictOptionalProperties2.ts @@ -0,0 +1,7 @@ +// @strict: true +// @declaration: true + +// Repro from #44567 + +type T1 = { 0?: string | undefined } extends { 0?: string } ? true : false; // false +type T2 = [(string | undefined)?] extends [string?] ? true : false; // false