diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ad09d843248..ebd849a7844 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11190,13 +11190,10 @@ namespace ts { } } - if (relation !== comparableRelation && - !(source.flags & TypeFlags.Union) && - !(target.flags & TypeFlags.Union) && - !isIntersectionConstituent && - source !== globalObjectType && + if (relation !== comparableRelation && !isIntersectionConstituent && + source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType && + target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) && (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)) && - isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { const calls = getSignaturesOfType(source, SignatureKind.Call); @@ -11841,6 +11838,9 @@ namespace ts { errorInfo = saveErrorInfo; } } + else if (isTupleType(source) && (isArrayType(target) || isReadonlyArrayType(target)) || isArrayType(source) && isReadonlyArrayType(target)) { + return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors); + } // Even if relationship doesn't hold for unions, intersections, or generic type references, // it may hold in a structural comparison. // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates @@ -12020,34 +12020,6 @@ namespace ts { return result; } - /** - * A type is 'weak' if it is an object type with at least one optional property - * and no required properties, call/construct signatures or index signatures - */ - function isWeakType(type: Type): boolean { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type); - return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && - !resolved.stringIndexInfo && !resolved.numberIndexInfo && - resolved.properties.length > 0 && - every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); - } - if (type.flags & TypeFlags.Intersection) { - return every((type).types, isWeakType); - } - return false; - } - - function hasCommonProperties(source: Type, target: Type) { - const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); - for (const prop of getPropertiesOfType(source)) { - if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { - return true; - } - } - return false; - } - function propertiesIdenticalTo(source: Type, target: Type): Ternary { if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) { return Ternary.False; @@ -12292,6 +12264,34 @@ namespace ts { } } + /** + * A type is 'weak' if it is an object type with at least one optional property + * and no required properties, call/construct signatures or index signatures + */ + function isWeakType(type: Type): boolean { + if (type.flags & TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type); + return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && + !resolved.stringIndexInfo && !resolved.numberIndexInfo && + resolved.properties.length > 0 && + every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); + } + if (type.flags & TypeFlags.Intersection) { + return every((type).types, isWeakType); + } + return false; + } + + function hasCommonProperties(source: Type, target: Type) { + const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); + for (const prop of getPropertiesOfType(source)) { + if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { + return true; + } + } + return false; + } + // Return a type reference where the source type parameter is replaced with the target marker // type, and flag the result as a marker type reference. function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) { diff --git a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt index 7ae20699c85..66a659b3863 100644 --- a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt +++ b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt @@ -1,13 +1,11 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. - Type 'A[]' is not assignable to type 'B[]'. - Type 'A' is not assignable to type 'B'. - Property 'b' is missing in type 'A'. + Type 'A' is not assignable to type 'B'. + Property 'b' is missing in type 'A'. tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. Type 'A[]' is not assignable to type 'B[]'. + Type 'A' is not assignable to type 'B'. ==== tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts (2 errors) ==== @@ -26,11 +24,8 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T rrb = ara; // error: 'A' is not assignable to 'B' ~~~ !!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. -!!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. -!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. -!!! error TS2322: Type 'A' is not assignable to type 'B'. -!!! error TS2322: Property 'b' is missing in type 'A'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Property 'b' is missing in type 'A'. rra = cra; rra = crb; // OK, C is assignable to ReadonlyArray @@ -41,4 +36,5 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T !!! error TS2322: Types of property 'concat' are incompatible. !!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. !!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt index 03dcee9baf3..b17973302c6 100644 --- a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt @@ -1,8 +1,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]'. Property '0' is missing in type '{}[]'. @@ -27,10 +25,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme numArray = numStrTuple; ~~~~~~~~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. emptyObjTuple = emptyObjArray; ~~~~~~~~~~~~~ !!! error TS2322: Type '{}[]' is not assignable to type '[{}]'. diff --git a/tests/baselines/reference/for-of39.errors.txt b/tests/baselines/reference/for-of39.errors.txt index 62edda40de3..5f084961833 100644 --- a/tests/baselines/reference/for-of39.errors.txt +++ b/tests/baselines/reference/for-of39.errors.txt @@ -1,24 +1,16 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,19): error TS2345: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'ReadonlyArray<[string, boolean]>'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray<[string, number] | [string, true]>[]): ([string, number] | [string, true])[]; (...items: ([string, number] | [string, true] | ConcatArray<[string, number] | [string, true]>)[]): ([string, number] | [string, true])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, boolean]>[]): [string, boolean][]; (...items: ([string, boolean] | ConcatArray<[string, boolean]>)[]): [string, boolean][]; }'. - Types of parameters 'items' and 'items' are incompatible. - Type 'ConcatArray<[string, boolean]>' is not assignable to type 'ConcatArray<[string, number] | [string, true]>'. - Type '[string, boolean]' is not assignable to type '[string, number] | [string, true]'. - Type '[string, boolean]' is not assignable to type '[string, number]'. - Type 'boolean' is not assignable to type 'number'. + Type '[string, number] | [string, true]' is not assignable to type '[string, boolean]'. + Type '[string, number]' is not assignable to type '[string, boolean]'. + Type 'number' is not assignable to type 'boolean'. ==== tests/cases/conformance/es6/for-ofStatements/for-of39.ts (1 errors) ==== var map = new Map([["", true], ["", 0]]); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'ReadonlyArray<[string, boolean]>'. -!!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: ConcatArray<[string, number] | [string, true]>[]): ([string, number] | [string, true])[]; (...items: ([string, number] | [string, true] | ConcatArray<[string, number] | [string, true]>)[]): ([string, number] | [string, true])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, boolean]>[]): [string, boolean][]; (...items: ([string, boolean] | ConcatArray<[string, boolean]>)[]): [string, boolean][]; }'. -!!! error TS2345: Types of parameters 'items' and 'items' are incompatible. -!!! error TS2345: Type 'ConcatArray<[string, boolean]>' is not assignable to type 'ConcatArray<[string, number] | [string, true]>'. -!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number] | [string, true]'. -!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. +!!! error TS2345: Type '[string, number] | [string, true]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type '[string, number]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type 'number' is not assignable to type 'boolean'. for (var [k, v] of map) { k; v; diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index 685b18932c1..71034e87edf 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -1,10 +1,15 @@ +error TS2321: Excessive stack depth comparing types 'Extract], Record<"val", string>>["val"]' and 'Extract>], Record<"val", string>>["val"]'. tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude]'. +tests/cases/compiler/infiniteConstraints.ts(27,37): error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(27,58): error TS2322: Type 'Record<"val", "test2">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(29,45): error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(31,43): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. -==== tests/cases/compiler/infiniteConstraints.ts (4 errors) ==== +!!! error TS2321: Excessive stack depth comparing types 'Extract], Record<"val", string>>["val"]' and 'Extract>], Record<"val", string>>["val"]'. +==== tests/cases/compiler/infiniteConstraints.ts (7 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; @@ -34,8 +39,17 @@ tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' c >(vals: T): void; const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2")}); + ~~~~ +!!! error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:27:37: The expected type comes from property 'main' which is declared here on type '{ main: never; alternate: never; }' + ~~~~~~~~~ +!!! error TS2322: Type 'Record<"val", "test2">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:27:58: The expected type comes from property 'alternate' which is declared here on type '{ main: never; alternate: never; }' const shouldBeNoError = ensureNoDuplicates({main: value("test")}); + ~~~~ +!!! error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:29:45: The expected type comes from property 'main' which is declared here on type '{ main: never; }' const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")}); ~~~~ diff --git a/tests/baselines/reference/infiniteConstraints.types b/tests/baselines/reference/infiniteConstraints.types index e23e138c820..7e357fbb01e 100644 --- a/tests/baselines/reference/infiniteConstraints.types +++ b/tests/baselines/reference/infiniteConstraints.types @@ -39,7 +39,7 @@ declare function value(val: V): Value; >val : V declare function ensureNoDuplicates< ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>ensureNoDuplicates : (vals: T) => void T extends { [K in keyof T]: Extract["val"] extends Extract], Value>["val"] @@ -50,9 +50,9 @@ declare function ensureNoDuplicates< >vals : T const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2")}); ->noError : void ->ensureNoDuplicates({main: value("test"), alternate: value("test2")}) : void ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>noError : any +>ensureNoDuplicates({main: value("test"), alternate: value("test2")}) : any +>ensureNoDuplicates : (vals: T) => void >{main: value("test"), alternate: value("test2")} : { main: Record<"val", "test">; alternate: Record<"val", "test2">; } >main : Record<"val", "test"> >value("test") : Record<"val", "test"> @@ -64,9 +64,9 @@ const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2 >"test2" : "test2" const shouldBeNoError = ensureNoDuplicates({main: value("test")}); ->shouldBeNoError : void ->ensureNoDuplicates({main: value("test")}) : void ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>shouldBeNoError : any +>ensureNoDuplicates({main: value("test")}) : any +>ensureNoDuplicates : (vals: T) => void >{main: value("test")} : { main: Record<"val", "test">; } >main : Record<"val", "test"> >value("test") : Record<"val", "test"> @@ -76,7 +76,7 @@ const shouldBeNoError = ensureNoDuplicates({main: value("test")}); const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")}); >shouldBeError : any >ensureNoDuplicates({main: value("dup"), alternate: value("dup")}) : any ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>ensureNoDuplicates : (vals: T) => void >{main: value("dup"), alternate: value("dup")} : { main: Record<"val", "dup">; alternate: Record<"val", "dup">; } >main : Record<"val", "dup"> >value("dup") : Record<"val", "dup"> diff --git a/tests/baselines/reference/iterableArrayPattern28.errors.txt b/tests/baselines/reference/iterableArrayPattern28.errors.txt index 7ca750cd81f..ecc9f0a02c5 100644 --- a/tests/baselines/reference/iterableArrayPattern28.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern28.errors.txt @@ -1,11 +1,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'. - Type '([string, number] | [string, boolean])[]' is not assignable to type '[string, number][]'. - Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. - Type '[string, boolean]' is not assignable to type '[string, number]'. - Type 'boolean' is not assignable to type 'number'. + Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. + Type '[string, boolean]' is not assignable to type '[string, number]'. + Type 'boolean' is not assignable to type 'number'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ==== @@ -15,9 +12,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error takeFirstTwoEntries(...new Map([["", 0], ["hello", true]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'. -!!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'. -!!! error TS2345: Type '([string, number] | [string, boolean])[]' is not assignable to type '[string, number][]'. -!!! error TS2345: Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. -!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file +!!! error TS2345: Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. +!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. +!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 87e17e14d3c..dd5fba3485d 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -9,15 +9,11 @@ tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, n Type '3' is not assignable to type '2'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(49,1): error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => number | {}' is not assignable to type '() => number'. - Type 'number | {}' is not assignable to type 'number'. - Type '{}' is not assignable to type 'number'. + 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'. tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. @@ -90,18 +86,14 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n a = a1; // Error ~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. a = a2; a = a3; // Error ~ !!! error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => number | {}' is not assignable to type '() => number'. -!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. -!!! error TS2322: Type '{}' is not assignable to type 'number'. +!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. +!!! error TS2322: Type '{}' is not assignable to type 'number'. a1 = a2; // Error ~~ !!! error TS2322: Type '[number, number]' is not assignable to type '[number, string]'.