From 7fd5fa850f215f54c74563006a7defb55e65f273 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 7 Feb 2019 14:10:25 -0800 Subject: [PATCH 1/4] Unify variance probing error exceptions between interfaces/aliases --- src/compiler/checker.ts | 68 ++--- .../reference/conditionalTypes1.errors.txt | 8 + .../mappedTypeRelationships.errors.txt | 4 + .../reference/mappedTypes5.errors.txt | 2 + .../strictFunctionTypesErrors.errors.txt | 82 ++---- ...unionTypeErrorMessageTypeRefs01.errors.txt | 18 +- ...derIndexSignatureRelationsAlign.errors.txt | 82 ++++++ ...ndZeroOrderIndexSignatureRelationsAlign.js | 146 +++++++++++ ...oOrderIndexSignatureRelationsAlign.symbols | 246 ++++++++++++++++++ ...eroOrderIndexSignatureRelationsAlign.types | 168 ++++++++++++ ...erIndexSignatureRelationsAlign2.errors.txt | 79 ++++++ ...dZeroOrderIndexSignatureRelationsAlign2.js | 146 +++++++++++ ...OrderIndexSignatureRelationsAlign2.symbols | 244 +++++++++++++++++ ...roOrderIndexSignatureRelationsAlign2.types | 165 ++++++++++++ ...ndZeroOrderIndexSignatureRelationsAlign.ts | 67 +++++ ...dZeroOrderIndexSignatureRelationsAlign2.ts | 67 +++++ 16 files changed, 1493 insertions(+), 99 deletions(-) create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types create mode 100644 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts create mode 100644 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f7cc72c534d05..acc24676e3560 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12579,11 +12579,10 @@ namespace ts { source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { const variances = getAliasVariances(source.aliasSymbol); - if (result = typeArgumentsRelatedTo(source.aliasTypeArguments, target.aliasTypeArguments, variances, reportErrors)) { - return result; + const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances); + if (varianceResult !== undefined) { + return varianceResult; } - originalErrorInfo = errorInfo; - errorInfo = saveErrorInfo; } if (target.flags & TypeFlags.TypeParameter) { @@ -12747,31 +12746,9 @@ namespace ts { // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. const variances = getVariances((source).target); - if (result = typeArgumentsRelatedTo((source).typeArguments, (target).typeArguments, variances, reportErrors)) { - return result; - } - // The type arguments did not relate appropriately, but it may be because we have no variance - // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type - // arguments). It might also be the case that the target type has a 'void' type argument for - // a covariant type parameter that is only used in return positions within the generic type - // (in which case any type argument is permitted on the source side). In those cases we proceed - // with a structural comparison. Otherwise, we know for certain the instantiations aren't - // related and we can return here. - if (variances !== emptyArray && !hasCovariantVoidArgument(target, variances)) { - // In some cases generic types that are covariant in regular type checking mode become - // invariant in --strictFunctionTypes mode because one or more type parameters are used in - // both co- and contravariant positions. In order to make it easier to diagnose *why* such - // types are invariant, if any of the type parameters are invariant we reset the reported - // errors and instead force a structural comparison (which will include elaborations that - // reveal the reason). - if (!(reportErrors && some(variances, v => v === Variance.Invariant))) { - return Ternary.False; - } - // We remember the original error information so we can restore it in case the structural - // comparison unexpectedly succeeds. This can happen when the structural comparison result - // is a Ternary.Maybe for example caused by the recursion depth limiter. - originalErrorInfo = errorInfo; - errorInfo = saveErrorInfo; + const varianceResult = relateVariances((source).typeArguments, (target).typeArguments, variances); + if (varianceResult !== undefined) { + return varianceResult; } } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { @@ -12808,6 +12785,35 @@ namespace ts { } } return Ternary.False; + + function relateVariances(sourceTypeArguments: ReadonlyArray | undefined, targetTypeArguments: ReadonlyArray | undefined, variances: Variance[]) { + if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors)) { + return result; + } + // The type arguments did not relate appropriately, but it may be because we have no variance + // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type + // arguments). It might also be the case that the target type has a 'void' type argument for + // a covariant type parameter that is only used in return positions within the generic type + // (in which case any type argument is permitted on the source side). In those cases we proceed + // with a structural comparison. Otherwise, we know for certain the instantiations aren't + // related and we can return here. + if (variances !== emptyArray && (!targetTypeArguments || !hasCovariantVoidArgument(targetTypeArguments, variances))) { + // In some cases generic types that are covariant in regular type checking mode become + // invariant in --strictFunctionTypes mode because one or more type parameters are used in + // both co- and contravariant positions. In order to make it easier to diagnose *why* such + // types are invariant, if any of the type parameters are invariant we reset the reported + // errors and instead force a structural comparison (which will include elaborations that + // reveal the reason). + if (!(reportErrors && some(variances, v => v === Variance.Invariant))) { + return Ternary.False; + } + // We remember the original error information so we can restore it in case the structural + // comparison unexpectedly succeeds. This can happen when the structural comparison result + // is a Ternary.Maybe for example caused by the recursion depth limiter. + originalErrorInfo = errorInfo; + errorInfo = saveErrorInfo; + } + } } // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is @@ -13324,9 +13330,9 @@ namespace ts { // Return true if the given type reference has a 'void' type argument for a covariant type parameter. // See comment at call in recursiveTypeRelatedTo for when this case matters. - function hasCovariantVoidArgument(type: TypeReference, variances: Variance[]): boolean { + function hasCovariantVoidArgument(typeArguments: ReadonlyArray, variances: Variance[]): boolean { for (let i = 0; i < variances.length; i++) { - if (variances[i] === Variance.Covariant && type.typeArguments![i].flags & TypeFlags.Void) { + if (variances[i] === Variance.Covariant && typeArguments[i].flags & TypeFlags.Void) { return true; } } diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 62239eca7b821..ec35f89161589 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -17,8 +17,12 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2 tests/cases/conformance/types/conditional/conditionalTypes1.ts(104,5): error TS2322: Type 'Pick' is not assignable to type 'T'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'never'. + Type 'string | number | symbol' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. @@ -183,11 +187,15 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS ~ !!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. !!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; z = y; // Error ~ !!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. } function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 60a06e000c255..3d63765407972 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -34,7 +34,9 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(72,5): error TS2322: Type 'Partial' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(78,5): error TS2322: Type 'Partial' is not assignable to type 'Partial'. + Type 'Thing' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(88,5): error TS2322: Type 'Readonly' is not assignable to type 'Readonly'. + Type 'Thing' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(127,5): error TS2322: Type 'Partial' is not assignable to type 'Identity'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. @@ -197,6 +199,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y = x; // Error ~ !!! error TS2322: Type 'Partial' is not assignable to type 'Partial'. +!!! error TS2322: Type 'Thing' is not assignable to type 'T'. } function f40(x: T, y: Readonly) { @@ -209,6 +212,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y = x; // Error ~ !!! error TS2322: Type 'Readonly' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'Thing' is not assignable to type 'T'. } type Item = { diff --git a/tests/baselines/reference/mappedTypes5.errors.txt b/tests/baselines/reference/mappedTypes5.errors.txt index d0c32cd1dd956..21d6f98964ae5 100644 --- a/tests/baselines/reference/mappedTypes5.errors.txt +++ b/tests/baselines/reference/mappedTypes5.errors.txt @@ -1,6 +1,7 @@ tests/cases/conformance/types/mapped/mappedTypes5.ts(6,9): error TS2322: Type 'Partial' is not assignable to type 'Readonly'. tests/cases/conformance/types/mapped/mappedTypes5.ts(8,9): error TS2322: Type 'Partial>' is not assignable to type 'Readonly'. tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. + Type 'Partial' is not assignable to type 'T'. ==== tests/cases/conformance/types/mapped/mappedTypes5.ts (3 errors) ==== @@ -19,6 +20,7 @@ tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'R let b4: Readonly = rp; // Error ~~ !!! error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'Partial' is not assignable to type 'T'. let c1: Partial> = p; let c2: Partial> = r; let c3: Partial> = pr; diff --git a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt index 369919850f085..3ff04c44fb75b 100644 --- a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt +++ b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt @@ -17,19 +17,15 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(21,1): error TS2322: Type '(x: tests/cases/compiler/strictFunctionTypesErrors.ts(23,1): error TS2322: Type '(x: string) => Object' is not assignable to type '(x: string) => string'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(33,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(34,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(36,1): error TS2322: Type 'Func' is not assignable to type 'Func'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(37,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(38,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(44,1): error TS2322: Type 'Func' is not assignable to type 'Func'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(46,1): error TS2322: Type 'Func' is not assignable to type 'Func'. @@ -39,37 +35,26 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(57,1): error TS2322: Type 'Fun tests/cases/compiler/strictFunctionTypesErrors.ts(58,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(61,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, Object>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(62,1): error TS2322: Type 'Func, string>' is not assignable to type 'Func, Object>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(65,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(66,1): error TS2322: Type 'Func, string>' is not assignable to type 'Func, string>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(67,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(74,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(75,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(76,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(79,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(80,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(83,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(84,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. @@ -162,13 +147,11 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c g1 = g3; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g1 = g4; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g2 = g1; // Error ~~ @@ -177,13 +160,11 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c g2 = g3; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g2 = g4; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g3 = g1; // Ok g3 = g2; // Ok @@ -221,29 +202,22 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c h3 = h1; // Error ~~ !!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, Object>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. h3 = h2; // Error ~~ !!! error TS2322: Type 'Func, string>' is not assignable to type 'Func, Object>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. h3 = h4; // Ok h4 = h1; // Error ~~ !!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. h4 = h2; // Error ~~ !!! error TS2322: Type 'Func, string>' is not assignable to type 'Func, string>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. h4 = h3; // Error ~~ !!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. @@ -261,25 +235,21 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c i1 = i3; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i1 = i4; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i2 = i1; // Ok i2 = i3; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i2 = i4; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i3 = i1; // Ok i3 = i2; // Error diff --git a/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt b/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt index 5fdeab58610af..ab661b6fee7c8 100644 --- a/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt +++ b/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt @@ -9,16 +9,13 @@ tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(27,1): error TS2322: Typ Property 'kwah' is missing in type 'Foo' but required in type 'Kwah'. tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(48,1): error TS2322: Type 'X' is not assignable to type 'X | Y | Z'. Type 'X' is not assignable to type 'X'. - Types of property 'xProp' are incompatible. - Type 'Foo' is not assignable to type 'Bar'. + Type 'Foo' is not assignable to type 'Bar'. tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(49,1): error TS2322: Type 'Y' is not assignable to type 'X | Y | Z'. Type 'Y' is not assignable to type 'Y'. - Types of property 'yProp' are incompatible. - Type 'Foo' is not assignable to type 'Baz'. + Type 'Foo' is not assignable to type 'Baz'. tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(50,1): error TS2322: Type 'Z' is not assignable to type 'X | Y | Z'. Type 'Z' is not assignable to type 'Z'. - Types of property 'zProp' are incompatible. - Type 'Foo' is not assignable to type 'Kwah'. + Type 'Foo' is not assignable to type 'Kwah'. ==== tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts (6 errors) ==== @@ -88,17 +85,14 @@ tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(50,1): error TS2322: Typ ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'X' is not assignable to type 'X | Y | Z'. !!! error TS2322: Type 'X' is not assignable to type 'X'. -!!! error TS2322: Types of property 'xProp' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Bar'. +!!! error TS2322: Type 'Foo' is not assignable to type 'Bar'. thingOfTypeAliases = y; ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'Y' is not assignable to type 'X | Y | Z'. !!! error TS2322: Type 'Y' is not assignable to type 'Y'. -!!! error TS2322: Types of property 'yProp' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Baz'. +!!! error TS2322: Type 'Foo' is not assignable to type 'Baz'. thingOfTypeAliases = z; ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'Z' is not assignable to type 'X | Y | Z'. !!! error TS2322: Type 'Z' is not assignable to type 'Z'. -!!! error TS2322: Types of property 'zProp' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Kwah'. \ No newline at end of file +!!! error TS2322: Type 'Foo' is not assignable to type 'Kwah'. \ No newline at end of file diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt new file mode 100644 index 0000000000000..47f97958f0d53 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt @@ -0,0 +1,82 @@ +tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts(63,6): error TS2345: Argument of type 'NeededInfo>' is not assignable to parameter of type 'NeededInfo<{}>'. + Types of property 'ASchema' are incompatible. + Type 'ToA>' is not assignable to type 'ToA<{}>'. + Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. +tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts(66,38): error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. + + +==== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts (2 errors) ==== + type Either = Left | Right; + + class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } + } + + class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } + } + + class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } + } + + interface Any extends Type {} + + type TypeOf = C["_A"]; + + type ToB = { [k in keyof S]: TypeOf }; + type ToA = { [k in keyof S]: Type }; + + type NeededInfo = { + ASchema: ToA; + }; + + export type MyInfo = NeededInfo>; + + const tmp1: MyInfo = null!; + function tmp2(n: N) {} + tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? + ~~~~ +!!! error TS2345: Argument of type 'NeededInfo>' is not assignable to parameter of type 'NeededInfo<{}>'. +!!! error TS2345: Types of property 'ASchema' are incompatible. +!!! error TS2345: Type 'ToA>' is not assignable to type 'ToA<{}>'. +!!! error TS2345: Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. +!!! related TS2728 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts:59:39: 'initialize' is declared here. + + class Server {} + export class MyServer extends Server {} // not assignable error at `MyInfo` + ~~~~~~ +!!! error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. \ No newline at end of file diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js new file mode 100644 index 0000000000000..cbac03d7a82cc --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js @@ -0,0 +1,146 @@ +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts] +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` + +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var Left = /** @class */ (function () { + function Left(value) { + this.value = value; + this._tag = 'Left'; + } + /** The given function is applied if this is a `Right` */ + Left.prototype.map = function (f) { + return this; + }; + Left.prototype.ap = function (fab) { + return null; + }; + return Left; +}()); +var Right = /** @class */ (function () { + function Right(value) { + this.value = value; + this._tag = 'Right'; + } + Right.prototype.map = function (f) { + return new Right(f(this.value)); + }; + Right.prototype.ap = function (fab) { + return null; + }; + return Right; +}()); +var Type = /** @class */ (function () { + function Type( + /** a unique name for this codec */ + name, + /** a custom type guard */ + is, + /** succeeds if a value of type I can be decoded to a value of type A */ + validate, + /** converts a value of type A to a value of type O */ + encode) { + this.name = name; + this.is = is; + this.validate = validate; + this.encode = encode; + } + /** a version of `validate` with a default context */ + Type.prototype.decode = function (i) { return null; }; + return Type; +}()); +var tmp1 = null; +function tmp2(n) { } +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? +var Server = /** @class */ (function () { + function Server() { + } + return Server; +}()); +var MyServer = /** @class */ (function (_super) { + __extends(MyServer, _super); + function MyServer() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyServer; +}(Server)); // not assignable error at `MyInfo` +exports.MyServer = MyServer; diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols new file mode 100644 index 0000000000000..bd9792840637a --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols @@ -0,0 +1,246 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts === +type Either = Left | Right; +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 14)) +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 14)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 14)) + +class Left { +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) + + readonly _tag: 'Left' = 'Left' +>_tag : Symbol(Left._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 18)) + + readonly _A!: A +>_A : Symbol(Left._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 3, 34)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) + + readonly _L!: L +>_L : Symbol(Left._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 4, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) + + constructor(readonly value: L) {} +>value : Symbol(Left.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 6, 16)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : Symbol(Left.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 6, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 8)) + + return this as any +>this : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 45)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Left.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 10, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 7)) + + return null as any + } +} + +class Right { +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) + + readonly _tag: 'Right' = 'Right' +>_tag : Symbol(Right._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 19)) + + readonly _A!: A +>_A : Symbol(Right._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 17, 36)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) + + readonly _L!: L +>_L : Symbol(Right._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 18, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) + + constructor(readonly value: A) {} +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 16)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) + + map(f: (a: A) => B): Either { +>map : Symbol(Right.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 8)) + + return new Right(f(this.value)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 11)) +>this.value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 16)) +>this : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 16)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Right.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 23, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 7)) + + return null as any; + } +} + +class Type { +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 27, 1)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 13)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) + + readonly _A!: A; +>_A : Symbol(Type._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 35)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) + + readonly _O!: O; +>_O : Symbol(Type._O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 30, 18)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 13)) + + readonly _I!: I; +>_I : Symbol(Type._I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 31, 18)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : Symbol(Type.name, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 33, 14)) + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : Symbol(Type.is, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 35, 26)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 37, 18)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 37, 18)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : Symbol(Type.validate, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 37, 40)) +>input : Symbol(input, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 39, 24)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) +>context : Symbol(context, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 39, 33)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : Symbol(Type.encode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 39, 68)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 41, 22)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 13)) + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : Symbol(Type.decode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 42, 6)) +>i : Symbol(i, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 44, 9)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +} + +interface Any extends Type {} +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 45, 1)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 27, 1)) + +type TypeOf = C["_A"]; +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 47, 44)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 12)) +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 45, 1)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 12)) + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 37)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 29)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 9)) +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 47, 44)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 29)) + +type ToA = { [k in keyof S]: Type }; +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 59)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 17)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 9)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 27, 1)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 17)) + +type NeededInfo = { +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 54, 16)) + + ASchema: ToA; +>ASchema : Symbol(ASchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 54, 43)) +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 59)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 54, 16)) + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 56, 2)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 37)) +>initialize : Symbol(initialize, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 58, 37)) + +const tmp1: MyInfo = null!; +>tmp1 : Symbol(tmp1, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 5)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 56, 2)) + +function tmp2(n: N) {} +>tmp2 : Symbol(tmp2, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 27)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 61, 14)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) +>n : Symbol(n, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 61, 36)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 61, 14)) + +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? +>tmp2 : Symbol(tmp2, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 27)) +>tmp1 : Symbol(tmp1, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 5)) + +class Server {} +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 62, 11)) +>X : Symbol(X, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 64, 13)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : Symbol(MyServer, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 64, 37)) +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 62, 11)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 56, 2)) + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types new file mode 100644 index 0000000000000..d360372d5aaee --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types @@ -0,0 +1,168 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts === +type Either = Left | Right; +>Either : Either + +class Left { +>Left : Left + + readonly _tag: 'Left' = 'Left' +>_tag : "Left" +>'Left' : "Left" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: L) {} +>value : L + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return this as any +>this as any : any +>this : this + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any +>null as any : any +>null : null + } +} + +class Right { +>Right : Right + + readonly _tag: 'Right' = 'Right' +>_tag : "Right" +>'Right' : "Right" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: A) {} +>value : A + + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return new Right(f(this.value)) +>new Right(f(this.value)) : Right +>Right : typeof Right +>f(this.value) : B +>f : (a: A) => B +>this.value : A +>this : this +>value : A + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any; +>null as any : any +>null : null + } +} + +class Type { +>Type : Type + + readonly _A!: A; +>_A : A + + readonly _O!: O; +>_O : O + + readonly _I!: I; +>_I : I + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : string + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : (u: unknown) => u is A +>u : unknown + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : (input: I, context: {}[]) => Either<{}[], A> +>input : I +>context : {}[] + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : (a: A) => O +>a : A + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : (i: I) => Either<{}[], A> +>i : I +>null as any : any +>null : null +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; +>TypeOf : C["_A"] + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : ToB + +type ToA = { [k in keyof S]: Type }; +>ToA : ToA + +type NeededInfo = { +>NeededInfo : NeededInfo + + ASchema: ToA; +>ASchema : ToA + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : NeededInfo> +>initialize : any + +const tmp1: MyInfo = null!; +>tmp1 : NeededInfo> +>null! : never +>null : null + +function tmp2(n: N) {} +>tmp2 : >(n: N) => void +>n : N + +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? +>tmp2(tmp1) : any +>tmp2 : >(n: N) => void +>tmp1 : NeededInfo> + +class Server {} +>Server : Server + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : MyServer +>Server : Server>> + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt new file mode 100644 index 0000000000000..aba1bc1db66d9 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt @@ -0,0 +1,79 @@ +tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts(66,38): error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. + Types of property 'ASchema' are incompatible. + Type 'ToA>' is not assignable to type 'ToA<{}>'. + Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. + + +==== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts (1 errors) ==== + type Either = Left | Right; + + class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } + } + + class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } + } + + class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } + } + + interface Any extends Type {} + + type TypeOf = C["_A"]; + + type ToB = { [k in keyof S]: TypeOf }; + type ToA = { [k in keyof S]: Type }; + + type NeededInfo = { + ASchema: ToA; + }; + + export type MyInfo = NeededInfo>; + + const tmp1: MyInfo = null!; + function tmp2(n: N) {} + // tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + + class Server {} + export class MyServer extends Server {} // not assignable error at `MyInfo` + ~~~~~~ +!!! error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. +!!! error TS2344: Types of property 'ASchema' are incompatible. +!!! error TS2344: Type 'ToA>' is not assignable to type 'ToA<{}>'. +!!! error TS2344: Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. +!!! related TS2728 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts:59:39: 'initialize' is declared here. \ No newline at end of file diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js new file mode 100644 index 0000000000000..8a4340ada95a6 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js @@ -0,0 +1,146 @@ +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts] +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` + +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var Left = /** @class */ (function () { + function Left(value) { + this.value = value; + this._tag = 'Left'; + } + /** The given function is applied if this is a `Right` */ + Left.prototype.map = function (f) { + return this; + }; + Left.prototype.ap = function (fab) { + return null; + }; + return Left; +}()); +var Right = /** @class */ (function () { + function Right(value) { + this.value = value; + this._tag = 'Right'; + } + Right.prototype.map = function (f) { + return new Right(f(this.value)); + }; + Right.prototype.ap = function (fab) { + return null; + }; + return Right; +}()); +var Type = /** @class */ (function () { + function Type( + /** a unique name for this codec */ + name, + /** a custom type guard */ + is, + /** succeeds if a value of type I can be decoded to a value of type A */ + validate, + /** converts a value of type A to a value of type O */ + encode) { + this.name = name; + this.is = is; + this.validate = validate; + this.encode = encode; + } + /** a version of `validate` with a default context */ + Type.prototype.decode = function (i) { return null; }; + return Type; +}()); +var tmp1 = null; +function tmp2(n) { } +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) +var Server = /** @class */ (function () { + function Server() { + } + return Server; +}()); +var MyServer = /** @class */ (function (_super) { + __extends(MyServer, _super); + function MyServer() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyServer; +}(Server)); // not assignable error at `MyInfo` +exports.MyServer = MyServer; diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols new file mode 100644 index 0000000000000..6d8983bd953d4 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols @@ -0,0 +1,244 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts === +type Either = Left | Right; +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 14)) +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 14)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 14)) + +class Left { +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) + + readonly _tag: 'Left' = 'Left' +>_tag : Symbol(Left._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 18)) + + readonly _A!: A +>_A : Symbol(Left._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 3, 34)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) + + readonly _L!: L +>_L : Symbol(Left._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 4, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) + + constructor(readonly value: L) {} +>value : Symbol(Left.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 6, 16)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : Symbol(Left.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 6, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 8)) + + return this as any +>this : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 45)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Left.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 10, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 7)) + + return null as any + } +} + +class Right { +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) + + readonly _tag: 'Right' = 'Right' +>_tag : Symbol(Right._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 19)) + + readonly _A!: A +>_A : Symbol(Right._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 17, 36)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) + + readonly _L!: L +>_L : Symbol(Right._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 18, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) + + constructor(readonly value: A) {} +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 16)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) + + map(f: (a: A) => B): Either { +>map : Symbol(Right.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 8)) + + return new Right(f(this.value)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 11)) +>this.value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 16)) +>this : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 16)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Right.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 23, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 7)) + + return null as any; + } +} + +class Type { +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 27, 1)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 13)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) + + readonly _A!: A; +>_A : Symbol(Type._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 35)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) + + readonly _O!: O; +>_O : Symbol(Type._O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 30, 18)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 13)) + + readonly _I!: I; +>_I : Symbol(Type._I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 31, 18)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : Symbol(Type.name, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 33, 14)) + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : Symbol(Type.is, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 35, 26)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 37, 18)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 37, 18)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : Symbol(Type.validate, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 37, 40)) +>input : Symbol(input, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 39, 24)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) +>context : Symbol(context, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 39, 33)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : Symbol(Type.encode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 39, 68)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 41, 22)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 13)) + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : Symbol(Type.decode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 42, 6)) +>i : Symbol(i, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 44, 9)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +} + +interface Any extends Type {} +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 45, 1)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 27, 1)) + +type TypeOf = C["_A"]; +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 47, 44)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 12)) +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 45, 1)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 12)) + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 37)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 29)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 9)) +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 47, 44)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 29)) + +type ToA = { [k in keyof S]: Type }; +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 59)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 17)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 9)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 27, 1)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 17)) + +type NeededInfo = { +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 54, 16)) + + ASchema: ToA; +>ASchema : Symbol(ASchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 54, 43)) +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 59)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 54, 16)) + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 56, 2)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 37)) +>initialize : Symbol(initialize, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 58, 37)) + +const tmp1: MyInfo = null!; +>tmp1 : Symbol(tmp1, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 60, 5)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 56, 2)) + +function tmp2(n: N) {} +>tmp2 : Symbol(tmp2, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 60, 27)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 14)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) +>n : Symbol(n, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 36)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 14)) + +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 44)) +>X : Symbol(X, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 64, 13)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : Symbol(MyServer, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 64, 37)) +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 44)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 56, 2)) + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types new file mode 100644 index 0000000000000..02a69f2fab0a5 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types @@ -0,0 +1,165 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts === +type Either = Left | Right; +>Either : Either + +class Left { +>Left : Left + + readonly _tag: 'Left' = 'Left' +>_tag : "Left" +>'Left' : "Left" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: L) {} +>value : L + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return this as any +>this as any : any +>this : this + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any +>null as any : any +>null : null + } +} + +class Right { +>Right : Right + + readonly _tag: 'Right' = 'Right' +>_tag : "Right" +>'Right' : "Right" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: A) {} +>value : A + + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return new Right(f(this.value)) +>new Right(f(this.value)) : Right +>Right : typeof Right +>f(this.value) : B +>f : (a: A) => B +>this.value : A +>this : this +>value : A + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any; +>null as any : any +>null : null + } +} + +class Type { +>Type : Type + + readonly _A!: A; +>_A : A + + readonly _O!: O; +>_O : O + + readonly _I!: I; +>_I : I + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : string + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : (u: unknown) => u is A +>u : unknown + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : (input: I, context: {}[]) => Either<{}[], A> +>input : I +>context : {}[] + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : (a: A) => O +>a : A + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : (i: I) => Either<{}[], A> +>i : I +>null as any : any +>null : null +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; +>TypeOf : C["_A"] + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : ToB + +type ToA = { [k in keyof S]: Type }; +>ToA : ToA + +type NeededInfo = { +>NeededInfo : NeededInfo + + ASchema: ToA; +>ASchema : ToA + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : NeededInfo> +>initialize : any + +const tmp1: MyInfo = null!; +>tmp1 : NeededInfo> +>null! : never +>null : null + +function tmp2(n: N) {} +>tmp2 : >(n: N) => void +>n : N + +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +>Server : Server + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : MyServer +>Server : Server>> + diff --git a/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts new file mode 100644 index 0000000000000..c84abda5e5617 --- /dev/null +++ b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts @@ -0,0 +1,67 @@ +// @strict: true +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` \ No newline at end of file diff --git a/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts new file mode 100644 index 0000000000000..14d835e618595 --- /dev/null +++ b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts @@ -0,0 +1,67 @@ +// @strict: true +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` \ No newline at end of file From 5c649d02b6410ee796230ef4f36b610c7b9625ad Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 7 Feb 2019 14:54:22 -0800 Subject: [PATCH 2/4] Consistiently return false on variance probe failure --- src/compiler/checker.ts | 24 ++++++++------ ...eckInfiniteExpansionTermination.errors.txt | 32 +++++++++++++++++++ .../reference/declarationEmitPromise.types | 28 ++++++++-------- .../recursiveTypeComparison.errors.txt | 27 ++++++++++++++++ ...ecursiveTypeInGenericConstraint.errors.txt | 27 ++++++++++++++++ .../recursiveTypeInGenericConstraint.types | 4 +-- ...wrappedAndRecursiveConstraints2.errors.txt | 12 +++++++ 7 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt create mode 100644 tests/baselines/reference/recursiveTypeComparison.errors.txt create mode 100644 tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt create mode 100644 tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index acc24676e3560..01e5435a85e76 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12570,6 +12570,7 @@ namespace ts { let result: Ternary; let originalErrorInfo: DiagnosticMessageChain | undefined; + let varianceCheckFailed = false; const saveErrorInfo = errorInfo; // We limit alias variance probing to only object and conditional types since their alias behavior @@ -12775,12 +12776,11 @@ namespace ts { } } } - if (result) { - if (!originalErrorInfo) { - errorInfo = saveErrorInfo; - return result; - } - errorInfo = originalErrorInfo; + if (varianceCheckFailed && result) { + errorInfo = originalErrorInfo || errorInfo || saveErrorInfo; // Use variance error (there is no structural one) and return false + } + else if (result) { + return result; } } } @@ -12790,6 +12790,8 @@ namespace ts { if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors)) { return result; } + const isCovariantVoid = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances); + varianceCheckFailed = !isCovariantVoid; // The type arguments did not relate appropriately, but it may be because we have no variance // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type // arguments). It might also be the case that the target type has a 'void' type argument for @@ -12797,14 +12799,16 @@ namespace ts { // (in which case any type argument is permitted on the source side). In those cases we proceed // with a structural comparison. Otherwise, we know for certain the instantiations aren't // related and we can return here. - if (variances !== emptyArray && (!targetTypeArguments || !hasCovariantVoidArgument(targetTypeArguments, variances))) { + if (variances !== emptyArray && !isCovariantVoid) { // In some cases generic types that are covariant in regular type checking mode become // invariant in --strictFunctionTypes mode because one or more type parameters are used in // both co- and contravariant positions. In order to make it easier to diagnose *why* such // types are invariant, if any of the type parameters are invariant we reset the reported // errors and instead force a structural comparison (which will include elaborations that // reveal the reason). - if (!(reportErrors && some(variances, v => v === Variance.Invariant))) { + // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`, + // we can return `False` early here to skip calculating the structural error message we don't need. + if (varianceCheckFailed && !(reportErrors && some(variances, v => v === Variance.Invariant))) { return Ternary.False; } // We remember the original error information so we can restore it in case the structural @@ -13331,8 +13335,8 @@ namespace ts { // Return true if the given type reference has a 'void' type argument for a covariant type parameter. // See comment at call in recursiveTypeRelatedTo for when this case matters. function hasCovariantVoidArgument(typeArguments: ReadonlyArray, variances: Variance[]): boolean { - for (let i = 0; i < variances.length; i++) { - if (variances[i] === Variance.Covariant && typeArguments[i].flags & TypeFlags.Void) { + for (let i = 0; i < typeArguments.length; i++) { + if ((!variances[i] || variances[i] === Variance.Covariant) && typeArguments[i].flags & TypeFlags.Void) { return true; } } diff --git a/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt b/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt new file mode 100644 index 0000000000000..014087ff6275e --- /dev/null +++ b/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/checkInfiniteExpansionTermination.ts(16,1): error TS2322: Type 'ISubject' is not assignable to type 'IObservable'. + Types of property 'n' are incompatible. + Type 'IObservable' is not assignable to type 'IObservable'. + Type 'Bar[]' is not assignable to type 'Foo[]'. + Property 'x' is missing in type 'Bar' but required in type 'Foo'. + + +==== tests/cases/compiler/checkInfiniteExpansionTermination.ts (1 errors) ==== + // Regression test for #1002 + // Before fix this code would cause infinite loop + + interface IObservable { + n: IObservable; // Needed, must be T[] + } + + // Needed + interface ISubject extends IObservable { } + + interface Foo { x } + interface Bar { y } + + var values: IObservable; + var values2: ISubject; + values = values2; + ~~~~~~ +!!! error TS2322: Type 'ISubject' is not assignable to type 'IObservable'. +!!! error TS2322: Types of property 'n' are incompatible. +!!! error TS2322: Type 'IObservable' is not assignable to type 'IObservable'. +!!! error TS2322: Type 'Bar[]' is not assignable to type 'Foo[]'. +!!! error TS2322: Property 'x' is missing in type 'Bar' but required in type 'Foo'. +!!! related TS2728 tests/cases/compiler/checkInfiniteExpansionTermination.ts:11:17: 'x' is declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitPromise.types b/tests/baselines/reference/declarationEmitPromise.types index f545baeb443bb..32629485803c7 100644 --- a/tests/baselines/reference/declarationEmitPromise.types +++ b/tests/baselines/reference/declarationEmitPromise.types @@ -25,20 +25,20 @@ export async function runSampleWorks( >bluebird.all : bluebird[] >bluebird : typeof bluebird >all : bluebird[] ->[a, b, c, d, e].filter(el => !!el) : bluebird[] ->[a, b, c, d, e].filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } ->[a, b, c, d, e] : bluebird[] +>[a, b, c, d, e].filter(el => !!el) : (bluebird | bluebird | bluebird | bluebird | bluebird)[] +>[a, b, c, d, e].filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } +>[a, b, c, d, e] : (bluebird | bluebird | bluebird | bluebird | bluebird)[] >a : bluebird >b : bluebird >c : bluebird >d : bluebird >e : bluebird ->filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } ->el => !!el : (el: bluebird) => boolean ->el : bluebird +>filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } +>el => !!el : (el: bluebird | bluebird | bluebird | bluebird | bluebird) => boolean +>el : bluebird | bluebird | bluebird | bluebird | bluebird >!!el : boolean >!el : boolean ->el : bluebird +>el : bluebird | bluebird | bluebird | bluebird | bluebird let func = (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 @@ -87,20 +87,20 @@ export async function runSampleBreaks( >bluebird.all : bluebird[] >bluebird : typeof bluebird >all : bluebird[] ->[a, b, c, d, e].filter(el => !!el) : bluebird[] ->[a, b, c, d, e].filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } ->[a, b, c, d, e] : bluebird[] +>[a, b, c, d, e].filter(el => !!el) : (bluebird | bluebird | bluebird | bluebird | bluebird)[] +>[a, b, c, d, e].filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } +>[a, b, c, d, e] : (bluebird | bluebird | bluebird | bluebird | bluebird)[] >a : bluebird >b : bluebird >c : bluebird >d : bluebird >e : bluebird ->filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } ->el => !!el : (el: bluebird) => boolean ->el : bluebird +>filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } +>el => !!el : (el: bluebird | bluebird | bluebird | bluebird | bluebird) => boolean +>el : bluebird | bluebird | bluebird | bluebird | bluebird >!!el : boolean >!el : boolean ->el : bluebird +>el : bluebird | bluebird | bluebird | bluebird | bluebird let func = (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 diff --git a/tests/baselines/reference/recursiveTypeComparison.errors.txt b/tests/baselines/reference/recursiveTypeComparison.errors.txt new file mode 100644 index 0000000000000..f647763b2e275 --- /dev/null +++ b/tests/baselines/reference/recursiveTypeComparison.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/recursiveTypeComparison.ts(14,5): error TS2322: Type 'Observable<{}>' is not assignable to type 'Property'. + Types of property 'needThisOne' are incompatible. + Type 'Observable<{}>' is not assignable to type 'Observable'. + Type '{}' is not assignable to type 'number'. + + +==== tests/cases/compiler/recursiveTypeComparison.ts (1 errors) ==== + // Before fix this would take an exceeding long time to complete (#1170) + + interface Observable { + // This member can't be of type T, Property, or Observable + needThisOne: Observable; + // Add more to make it slower + expo1: Property; // 0.31 seconds in check + expo2: Property; // 3.11 seconds + expo3: Property; // 82.28 seconds + } + interface Property extends Observable { } + + var p: Observable<{}>; + var stuck: Property = p; + ~~~~~ +!!! error TS2322: Type 'Observable<{}>' is not assignable to type 'Property'. +!!! error TS2322: Types of property 'needThisOne' are incompatible. +!!! error TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. +!!! error TS2322: Type '{}' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt b/tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt new file mode 100644 index 0000000000000..a9f514c42c7e3 --- /dev/null +++ b/tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeInGenericConstraint.ts(13,18): error TS2344: Type 'D' does not satisfy the constraint 'G>'. + Types of property 'x' are incompatible. + Type 'G>' is not assignable to type 'G>>'. + Type 'G' is not assignable to type 'G>'. + Type 'string' is not assignable to type 'D'. + + +==== tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeInGenericConstraint.ts (1 errors) ==== + class G { + x: G>; // infinitely expanding type reference + } + + class Foo> { // error, constraint referencing itself + bar: T; + } + + class D { + x: G>; + } + + var c1 = new Foo>(); // ok, circularity in assignment compat check causes success + ~~~~~~~~~ +!!! error TS2344: Type 'D' does not satisfy the constraint 'G>'. +!!! error TS2344: Types of property 'x' are incompatible. +!!! error TS2344: Type 'G>' is not assignable to type 'G>>'. +!!! error TS2344: Type 'G' is not assignable to type 'G>'. +!!! error TS2344: Type 'string' is not assignable to type 'D'. \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeInGenericConstraint.types b/tests/baselines/reference/recursiveTypeInGenericConstraint.types index 32180d9453fc6..61d67a98a6a91 100644 --- a/tests/baselines/reference/recursiveTypeInGenericConstraint.types +++ b/tests/baselines/reference/recursiveTypeInGenericConstraint.types @@ -21,7 +21,7 @@ class D { } var c1 = new Foo>(); // ok, circularity in assignment compat check causes success ->c1 : Foo> ->new Foo>() : Foo> +>c1 : any +>new Foo>() : any >Foo : typeof Foo diff --git a/tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt b/tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt new file mode 100644 index 0000000000000..a443e72497b3f --- /dev/null +++ b/tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints2.ts(6,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'C', but here has type 'C>'. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints2.ts (1 errors) ==== + class C> { // error + constructor(x: T) { } + } + + var c = new C(1); + var c = new C(new C('')); // error + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'C', but here has type 'C>'. \ No newline at end of file From 7067bfb2e72258f171c0d9a970e42b92fbcef4d4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 7 Feb 2019 14:59:47 -0800 Subject: [PATCH 3/4] Remove strictFunctionTypes early bail from getVariances so independent type parameters are correctly measured --- src/compiler/checker.ts | 2 +- .../complexRecursiveCollections.types | 2 +- .../reference/declarationEmitPromise.types | 28 +++++++++---------- ...ecursiveTypeInGenericConstraint.errors.txt | 27 ------------------ .../recursiveTypeInGenericConstraint.types | 4 +-- ...wrappedAndRecursiveConstraints2.errors.txt | 12 -------- 6 files changed, 18 insertions(+), 57 deletions(-) delete mode 100644 tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt delete mode 100644 tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 01e5435a85e76..3ca00d7c429e8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13326,7 +13326,7 @@ namespace ts { function getVariances(type: GenericType): Variance[] { // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) - if (!strictFunctionTypes || type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { + if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { return emptyArray; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); diff --git a/tests/baselines/reference/complexRecursiveCollections.types b/tests/baselines/reference/complexRecursiveCollections.types index a9fc13e7d1dc1..feaff62048628 100644 --- a/tests/baselines/reference/complexRecursiveCollections.types +++ b/tests/baselines/reference/complexRecursiveCollections.types @@ -1137,7 +1137,7 @@ declare module Immutable { >Seq : typeof Seq function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed | Seq.Keyed; ->isSeq : (maybeSeq: any) => maybeSeq is Keyed | Indexed +>isSeq : (maybeSeq: any) => maybeSeq is Indexed | Keyed >maybeSeq : any >Seq : any >Seq : any diff --git a/tests/baselines/reference/declarationEmitPromise.types b/tests/baselines/reference/declarationEmitPromise.types index 32629485803c7..f545baeb443bb 100644 --- a/tests/baselines/reference/declarationEmitPromise.types +++ b/tests/baselines/reference/declarationEmitPromise.types @@ -25,20 +25,20 @@ export async function runSampleWorks( >bluebird.all : bluebird[] >bluebird : typeof bluebird >all : bluebird[] ->[a, b, c, d, e].filter(el => !!el) : (bluebird | bluebird | bluebird | bluebird | bluebird)[] ->[a, b, c, d, e].filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } ->[a, b, c, d, e] : (bluebird | bluebird | bluebird | bluebird | bluebird)[] +>[a, b, c, d, e].filter(el => !!el) : bluebird[] +>[a, b, c, d, e].filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } +>[a, b, c, d, e] : bluebird[] >a : bluebird >b : bluebird >c : bluebird >d : bluebird >e : bluebird ->filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } ->el => !!el : (el: bluebird | bluebird | bluebird | bluebird | bluebird) => boolean ->el : bluebird | bluebird | bluebird | bluebird | bluebird +>filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } +>el => !!el : (el: bluebird) => boolean +>el : bluebird >!!el : boolean >!el : boolean ->el : bluebird | bluebird | bluebird | bluebird | bluebird +>el : bluebird let func = (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 @@ -87,20 +87,20 @@ export async function runSampleBreaks( >bluebird.all : bluebird[] >bluebird : typeof bluebird >all : bluebird[] ->[a, b, c, d, e].filter(el => !!el) : (bluebird | bluebird | bluebird | bluebird | bluebird)[] ->[a, b, c, d, e].filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } ->[a, b, c, d, e] : (bluebird | bluebird | bluebird | bluebird | bluebird)[] +>[a, b, c, d, e].filter(el => !!el) : bluebird[] +>[a, b, c, d, e].filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } +>[a, b, c, d, e] : bluebird[] >a : bluebird >b : bluebird >c : bluebird >d : bluebird >e : bluebird ->filter : { | bluebird | bluebird | bluebird | bluebird>(callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird | bluebird | bluebird | bluebird | bluebird, index: number, array: (bluebird | bluebird | bluebird | bluebird | bluebird)[]) => any, thisArg?: any): (bluebird | bluebird | bluebird | bluebird | bluebird)[]; } ->el => !!el : (el: bluebird | bluebird | bluebird | bluebird | bluebird) => boolean ->el : bluebird | bluebird | bluebird | bluebird | bluebird +>filter : { >(callbackfn: (value: bluebird, index: number, array: bluebird[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any): bluebird[]; } +>el => !!el : (el: bluebird) => boolean +>el : bluebird >!!el : boolean >!el : boolean ->el : bluebird | bluebird | bluebird | bluebird | bluebird +>el : bluebird let func = (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 diff --git a/tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt b/tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt deleted file mode 100644 index a9f514c42c7e3..0000000000000 --- a/tests/baselines/reference/recursiveTypeInGenericConstraint.errors.txt +++ /dev/null @@ -1,27 +0,0 @@ -tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeInGenericConstraint.ts(13,18): error TS2344: Type 'D' does not satisfy the constraint 'G>'. - Types of property 'x' are incompatible. - Type 'G>' is not assignable to type 'G>>'. - Type 'G' is not assignable to type 'G>'. - Type 'string' is not assignable to type 'D'. - - -==== tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeInGenericConstraint.ts (1 errors) ==== - class G { - x: G>; // infinitely expanding type reference - } - - class Foo> { // error, constraint referencing itself - bar: T; - } - - class D { - x: G>; - } - - var c1 = new Foo>(); // ok, circularity in assignment compat check causes success - ~~~~~~~~~ -!!! error TS2344: Type 'D' does not satisfy the constraint 'G>'. -!!! error TS2344: Types of property 'x' are incompatible. -!!! error TS2344: Type 'G>' is not assignable to type 'G>>'. -!!! error TS2344: Type 'G' is not assignable to type 'G>'. -!!! error TS2344: Type 'string' is not assignable to type 'D'. \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeInGenericConstraint.types b/tests/baselines/reference/recursiveTypeInGenericConstraint.types index 61d67a98a6a91..32180d9453fc6 100644 --- a/tests/baselines/reference/recursiveTypeInGenericConstraint.types +++ b/tests/baselines/reference/recursiveTypeInGenericConstraint.types @@ -21,7 +21,7 @@ class D { } var c1 = new Foo>(); // ok, circularity in assignment compat check causes success ->c1 : any ->new Foo>() : any +>c1 : Foo> +>new Foo>() : Foo> >Foo : typeof Foo diff --git a/tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt b/tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt deleted file mode 100644 index a443e72497b3f..0000000000000 --- a/tests/baselines/reference/wrappedAndRecursiveConstraints2.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints2.ts(6,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'C', but here has type 'C>'. - - -==== tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints2.ts (1 errors) ==== - class C> { // error - constructor(x: T) { } - } - - var c = new C(1); - var c = new C(new C('')); // error - ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'C', but here has type 'C>'. \ No newline at end of file From d2cdfc263918b29159fed9465993591a00b17aaa Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 7 Feb 2019 15:14:26 -0800 Subject: [PATCH 4/4] Fix lint, remove now-redundant change from covariant void check function --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ca00d7c429e8..b5bd00babdc33 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12807,7 +12807,7 @@ namespace ts { // errors and instead force a structural comparison (which will include elaborations that // reveal the reason). // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`, - // we can return `False` early here to skip calculating the structural error message we don't need. + // we can return `False` early here to skip calculating the structural error message we don't need. if (varianceCheckFailed && !(reportErrors && some(variances, v => v === Variance.Invariant))) { return Ternary.False; } @@ -13335,8 +13335,8 @@ namespace ts { // Return true if the given type reference has a 'void' type argument for a covariant type parameter. // See comment at call in recursiveTypeRelatedTo for when this case matters. function hasCovariantVoidArgument(typeArguments: ReadonlyArray, variances: Variance[]): boolean { - for (let i = 0; i < typeArguments.length; i++) { - if ((!variances[i] || variances[i] === Variance.Covariant) && typeArguments[i].flags & TypeFlags.Void) { + for (let i = 0; i < variances.length; i++) { + if (variances[i] === Variance.Covariant && typeArguments[i].flags & TypeFlags.Void) { return true; } }