diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb52a13176aca..25f3f41bc4dc5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16626,6 +16626,7 @@ namespace ts { return result; } + function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]) { const declaration = type.objectFlags & ObjectFlags.Reference ? (type as TypeReference).node! : type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node : @@ -16683,15 +16684,16 @@ namespace ts { } function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { - // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks - // between the node and the type parameter declaration, if the node contains actual references to the - // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. - if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { - const container = tp.symbol.declarations[0].parent; - for (let n = node; n !== container; n = n.parent) { + // If there are intervening statement blocks between the node and the type parameter declaration, if the node + // contains actual references to the type parameter, or if the node contains type queries, we consider the + // type parameter possibly referenced. + if (tp.symbol && tp.symbol.declarations) { + let n = node; + while (!some(tp.symbol.declarations, d => n === d.parent)) { if (!n || n.kind === SyntaxKind.Block || n.kind === SyntaxKind.ConditionalType && forEachChild((n as ConditionalTypeNode).extendsType, containsReference)) { return true; } + n = n.parent; } return containsReference(node); } @@ -17947,7 +17949,7 @@ namespace ts { } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { const related = relation.get(getRelationKey(source, target, IntersectionState.None, relation, /*ignoreConstraints*/ false)); - if (related !== undefined) { + if (related !== undefined && !(related & RelationComparisonResult.ReportsMask)) { return !!(related & RelationComparisonResult.Succeeded); } } @@ -19049,16 +19051,16 @@ namespace ts { // We limit alias variance probing to only object and conditional types since their alias behavior // is more predictable than other, interned types, which may or may not have an alias depending on // the order in which things were checked. - if (sourceFlags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol && - source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && - !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { + if (sourceFlags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) { const variances = getAliasVariances(source.aliasSymbol); - if (variances === emptyArray) { - return Ternary.Unknown; + if (variances !== emptyArray) { + const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); + if (varianceResult !== undefined) { + return varianceResult; + } } - const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); - if (varianceResult !== undefined) { - return varianceResult; + else if (!someContainsMarkerType(source.aliasTypeArguments) && !someContainsMarkerType(target.aliasTypeArguments)) { + return Ternary.Unknown; } } @@ -19429,26 +19431,25 @@ namespace ts { else if (isGenericMappedType(source)) { return Ternary.False; } - if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source as TypeReference).target === (target as TypeReference).target && - !isTupleType(source) && !(getObjectFlags(source) & ObjectFlags.MarkerType || getObjectFlags(target) & ObjectFlags.MarkerType)) { + if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source as TypeReference).target === (target as TypeReference).target && !isTupleType(source)) { // When strictNullChecks is disabled, the element type of the empty array literal is undefinedWideningType, // and an empty array literal wouldn't be assignable to a `never[]` without this check. if (isEmptyArrayLiteralType(source)) { return Ternary.True; } - // We have type references to the same generic type, and the type references are not marker - // type references (which are intended by be compared structurally). Obtain the variance - // information for the type parameters and relate the type arguments accordingly. + // We have type references to the same generic type. Obtain the variance information for the type + // parameters and relate the type arguments accordingly. If variance information for the type is in + // the process of being computed, structurally relate references that contain marker types in their + // type arguments, but otherwise return Ternary.Unknown (the non-cached version of Ternary.Maybe). const variances = getVariances((source as TypeReference).target); - // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This - // effectively means we measure variance only from type parameter occurrences that aren't nested in - // recursive instantiations of the generic type. - if (variances === emptyArray) { - return Ternary.Unknown; + if (variances !== emptyArray) { + const varianceResult = relateVariances(getTypeArguments(source as TypeReference), getTypeArguments(target as TypeReference), variances, intersectionState); + if (varianceResult !== undefined) { + return varianceResult; + } } - const varianceResult = relateVariances(getTypeArguments(source as TypeReference), getTypeArguments(target as TypeReference), variances, intersectionState); - if (varianceResult !== undefined) { - return varianceResult; + else if (!someContainsMarkerType(getTypeArguments(source as TypeReference)) && !someContainsMarkerType(getTypeArguments(target as TypeReference))) { + return Ternary.Unknown; } } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { @@ -20366,21 +20367,15 @@ namespace ts { return false; } - // Return a type reference where the source type parameter is replaced with the target marker - // type, and flag the result as a marker type reference. - function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) { - const result = createTypeReference(type, map(type.typeParameters, t => t === source ? target : t)); - result.objectFlags |= ObjectFlags.MarkerType; - return result; + function getVariances(type: GenericType): VarianceFlags[] { + // Arrays and tuples are known to be covariant, no need to spend time computing this. + return type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple ? + arrayVariances : + getVariancesWorker(type.symbol, type.typeParameters); } function getAliasVariances(symbol: Symbol) { - const links = getSymbolLinks(symbol); - return getVariancesWorker(links.typeParameters, links, (_links, param, marker) => { - const type = getTypeAliasInstantiation(symbol, instantiateTypes(links.typeParameters!, makeUnaryTypeMapper(param, marker))); - type.aliasTypeArgumentsContainsMarker = true; - return type; - }); + return getVariancesWorker(symbol, getSymbolLinks(symbol).typeParameters); } // Return an array containing the variance of each type parameter. The variance is effectively @@ -20388,13 +20383,12 @@ namespace ts { // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function // returns the emptyArray singleton when invoked recursively for the given generic type. - function getVariancesWorker(typeParameters: readonly TypeParameter[] = emptyArray, cache: TCache, createMarkerType: (input: TCache, param: TypeParameter, marker: Type) => Type): VarianceFlags[] { - let variances = cache.variances; - if (!variances) { - tracing?.push(tracing.Phase.CheckTypes, "getVariancesWorker", { arity: typeParameters.length, id: (cache as any).id ?? (cache as any).declaredType?.id ?? -1 }); - // The emptyArray singleton is used to signal a recursive invocation. - cache.variances = emptyArray; - variances = []; + function getVariancesWorker(symbol: Symbol, typeParameters: readonly TypeParameter[] = emptyArray): VarianceFlags[] { + const links = getSymbolLinks(symbol); + if (!links.variances) { + tracing?.push(tracing.Phase.CheckTypes, "getVariancesWorker", { arity: typeParameters.length, id: getTypeId(getDeclaredTypeOfSymbol(symbol)) }); + links.variances = emptyArray; + const variances = []; for (const tp of typeParameters) { let unmeasurable = false; let unreliable = false; @@ -20403,15 +20397,15 @@ namespace ts { // We first compare instantiations where the type parameter is replaced with // marker types that have a known subtype relationship. From this we can infer // invariance, covariance, contravariance or bivariance. - const typeWithSuper = createMarkerType(cache, tp, markerSuperType); - const typeWithSub = createMarkerType(cache, tp, markerSubType); + const typeWithSuper = createMarkerType(symbol, tp, markerSuperType); + const typeWithSub = createMarkerType(symbol, tp, markerSubType); let variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? VarianceFlags.Covariant : 0) | (isTypeAssignableTo(typeWithSuper, typeWithSub) ? VarianceFlags.Contravariant : 0); // If the instantiations appear to be related bivariantly it may be because the // type parameter is independent (i.e. it isn't witnessed anywhere in the generic // type). To determine this we compare instantiations where the type parameter is // replaced with marker types that are known to be unrelated. - if (variance === VarianceFlags.Bivariant && isTypeAssignableTo(createMarkerType(cache, tp, markerOtherType), typeWithSuper)) { + if (variance === VarianceFlags.Bivariant && isTypeAssignableTo(createMarkerType(symbol, tp, markerOtherType), typeWithSuper)) { variance = VarianceFlags.Independent; } outofbandVarianceMarkerHandler = oldHandler; @@ -20425,18 +20419,62 @@ namespace ts { } variances.push(variance); } - cache.variances = variances; + links.variances = variances; tracing?.pop(); } - return variances; + return links.variances; } - function getVariances(type: GenericType): VarianceFlags[] { - // Arrays and tuples are known to be covariant, no need to spend time computing this. - if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { - return arrayVariances; + function createMarkerType(symbol: Symbol, source: TypeParameter, target: Type) { + const mapper = makeUnaryTypeMapper(source, target); + if (symbol.flags & SymbolFlags.TypeAlias) { + return getTypeAliasInstantiation(symbol, instantiateTypes(getSymbolLinks(symbol).typeParameters!, mapper)); } - return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); + const type = getDeclaredTypeOfSymbol(symbol) as GenericType; + return createTypeReference(type, instantiateTypes(type.typeParameters, mapper)); + } + + // Check if any of the given types contain marker types. We visit type arguments of generic classes, interfaces, and + // type aliases, members of anonymous type literals and mapped types, constituents of union, intersection, and + // template literal types, and targets of index types and string mapping types. This is by design a limited set of + // types to avoid excessive fan out. In deferred (and thus possibly circular) locations we limit the traversal to + // four levels of depth. + function someContainsMarkerType(types: readonly Type[] | undefined, maxDepth = 4) { + return some(types, t => containsMarkerType(t, maxDepth)); + } + + function containsMarkerType(type: Type, maxDepth: number): boolean { + return maxDepth > 0 && ( + type.flags & TypeFlags.TypeParameter ? type === markerSubType || type === markerSubType || type === markerOtherType : + type.aliasSymbol ? someContainsMarkerType(type.aliasTypeArguments, maxDepth) : + type.flags & TypeFlags.Object ? objectTypeContainsMarkerType(type as ObjectType, maxDepth) : + type.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral) && !(type.flags & TypeFlags.EnumLiteral) ? someContainsMarkerType((type as UnionOrIntersectionType | TemplateLiteralType).types, maxDepth) : + type.flags & (TypeFlags.Index | TypeFlags.StringMapping) ? containsMarkerType((type as IndexType | StringMappingType).type, maxDepth) : + false); + } + + function objectTypeContainsMarkerType(type: ObjectType, maxDepth: number): boolean { + const objectFlags = getObjectFlags(type); + if (objectFlags & ObjectFlags.Reference) { + return someContainsMarkerType(getTypeArguments(type as TypeReference), maxDepth - ((type as TypeReference).node ? 1 : 0)); + } + if (objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.TypeLiteral) { + const resolved = resolveStructuredTypeMembers(type); + return some(resolved.properties, prop => containsMarkerType(getTypeOfSymbol(prop), maxDepth - 1)) || + some(resolved.callSignatures, sig => signatureContainsMarkerType(sig, maxDepth)) || + some(resolved.constructSignatures, sig => signatureContainsMarkerType(sig, maxDepth)) || + some(resolved.indexInfos, info => containsMarkerType(info.type, maxDepth - 1)); + } + if (objectFlags & ObjectFlags.Mapped) { + return containsMarkerType(getConstraintTypeFromMappedType(type as MappedType), maxDepth - 1) || + containsMarkerType(getTemplateTypeFromMappedType(type as MappedType), maxDepth - 1); + } + return false; + } + + function signatureContainsMarkerType(sig: Signature, maxDepth: number): boolean { + return some(sig.parameters, param => containsMarkerType(getTypeOfSymbol(param), maxDepth - 1)) || + containsMarkerType(getReturnTypeOfSignature(sig), maxDepth - 1); } // Return true if the given type reference has a 'void' type argument for a covariant type parameter. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 54936e787bc7a..991cb088b163f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5227,7 +5227,6 @@ namespace ts { pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any) aliasSymbol?: Symbol; // Alias associated with type aliasTypeArguments?: readonly Type[]; // Alias type arguments (if any) - /* @internal */ aliasTypeArgumentsContainsMarker?: boolean; // Alias type arguments (if any) /* @internal */ permissiveInstantiation?: Type; // Instantiation with type parameters mapped to wildcard type /* @internal */ @@ -5306,22 +5305,21 @@ namespace ts { ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties ReverseMapped = 1 << 10, // Object contains a property from a reverse-mapped type JsxAttributes = 1 << 11, // Jsx attributes type - MarkerType = 1 << 12, // Marker type used for variance probing - JSLiteral = 1 << 13, // Object type declared in JS - disables errors on read/write of nonexisting members - FreshLiteral = 1 << 14, // Fresh object literal - ArrayLiteral = 1 << 15, // Originates in an array literal + JSLiteral = 1 << 12, // Object type declared in JS - disables errors on read/write of nonexisting members + FreshLiteral = 1 << 13, // Fresh object literal + ArrayLiteral = 1 << 14, // Originates in an array literal /* @internal */ - PrimitiveUnion = 1 << 16, // Union of only primitive types + PrimitiveUnion = 1 << 15, // Union of only primitive types /* @internal */ - ContainsWideningType = 1 << 17, // Type is or contains undefined or null widening type + ContainsWideningType = 1 << 16, // Type is or contains undefined or null widening type /* @internal */ - ContainsObjectOrArrayLiteral = 1 << 18, // Type is or contains object literal type + ContainsObjectOrArrayLiteral = 1 << 17, // Type is or contains object literal type /* @internal */ - NonInferrableType = 1 << 19, // Type is or contains anyFunctionType or silentNeverType + NonInferrableType = 1 << 18, // Type is or contains anyFunctionType or silentNeverType /* @internal */ - CouldContainTypeVariablesComputed = 1 << 20, // CouldContainTypeVariables flag has been computed + CouldContainTypeVariablesComputed = 1 << 19, // CouldContainTypeVariables flag has been computed /* @internal */ - CouldContainTypeVariables = 1 << 21, // Type could contain a type variable + CouldContainTypeVariables = 1 << 20, // Type could contain a type variable ClassOrInterface = Class | Interface, /* @internal */ @@ -5333,36 +5331,36 @@ namespace ts { ObjectTypeKindMask = ClassOrInterface | Reference | Tuple | Anonymous | Mapped | ReverseMapped | EvolvingArray, // Flags that require TypeFlags.Object - ContainsSpread = 1 << 22, // Object literal contains spread operation - ObjectRestType = 1 << 23, // Originates in object rest declaration - InstantiationExpressionType = 1 << 24, // Originates in instantiation expression + ContainsSpread = 1 << 21, // Object literal contains spread operation + ObjectRestType = 1 << 22, // Originates in object rest declaration + InstantiationExpressionType = 1 << 23, // Originates in instantiation expression /* @internal */ - IsClassInstanceClone = 1 << 25, // Type is a clone of a class instance type + IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type // Flags that require TypeFlags.Object and ObjectFlags.Reference /* @internal */ - IdenticalBaseTypeCalculated = 1 << 26, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already + IdenticalBaseTypeCalculated = 1 << 25, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already /* @internal */ - IdenticalBaseTypeExists = 1 << 27, // has a defined cachedEquivalentBaseType member + IdenticalBaseTypeExists = 1 << 26, // has a defined cachedEquivalentBaseType member // Flags that require TypeFlags.UnionOrIntersection or TypeFlags.Substitution /* @internal */ - IsGenericTypeComputed = 1 << 22, // IsGenericObjectType flag has been computed + IsGenericTypeComputed = 1 << 21, // IsGenericObjectType flag has been computed /* @internal */ - IsGenericObjectType = 1 << 23, // Union or intersection contains generic object type + IsGenericObjectType = 1 << 22, // Union or intersection contains generic object type /* @internal */ - IsGenericIndexType = 1 << 24, // Union or intersection contains generic index type + IsGenericIndexType = 1 << 23, // Union or intersection contains generic index type /* @internal */ IsGenericType = IsGenericObjectType | IsGenericIndexType, // Flags that require TypeFlags.Union /* @internal */ - ContainsIntersections = 1 << 25, // Union contains intersections + ContainsIntersections = 1 << 24, // Union contains intersections // Flags that require TypeFlags.Intersection /* @internal */ - IsNeverIntersectionComputed = 1 << 25, // IsNeverLike flag has been computed + IsNeverIntersectionComputed = 1 << 24, // IsNeverLike flag has been computed /* @internal */ - IsNeverIntersection = 1 << 26, // Intersection reduces to never + IsNeverIntersection = 1 << 25, // Intersection reduces to never } /* @internal */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 255fb6a1305c7..21c4593a9886f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2654,14 +2654,13 @@ declare namespace ts { ObjectLiteralPatternWithComputedProperties = 512, ReverseMapped = 1024, JsxAttributes = 2048, - MarkerType = 4096, - JSLiteral = 8192, - FreshLiteral = 16384, - ArrayLiteral = 32768, + JSLiteral = 4096, + FreshLiteral = 8192, + ArrayLiteral = 16384, ClassOrInterface = 3, - ContainsSpread = 4194304, - ObjectRestType = 8388608, - InstantiationExpressionType = 16777216, + ContainsSpread = 2097152, + ObjectRestType = 4194304, + InstantiationExpressionType = 8388608, } export interface ObjectType extends Type { objectFlags: ObjectFlags; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 63a6a9bc49be3..4637193338298 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2654,14 +2654,13 @@ declare namespace ts { ObjectLiteralPatternWithComputedProperties = 512, ReverseMapped = 1024, JsxAttributes = 2048, - MarkerType = 4096, - JSLiteral = 8192, - FreshLiteral = 16384, - ArrayLiteral = 32768, + JSLiteral = 4096, + FreshLiteral = 8192, + ArrayLiteral = 16384, ClassOrInterface = 3, - ContainsSpread = 4194304, - ObjectRestType = 8388608, - InstantiationExpressionType = 16777216, + ContainsSpread = 2097152, + ObjectRestType = 4194304, + InstantiationExpressionType = 8388608, } export interface ObjectType extends Type { objectFlags: ObjectFlags; diff --git a/tests/baselines/reference/bivariantInferences.symbols b/tests/baselines/reference/bivariantInferences.symbols index 0697c171c54e8..f7b25569d8cd3 100644 --- a/tests/baselines/reference/bivariantInferences.symbols +++ b/tests/baselines/reference/bivariantInferences.symbols @@ -24,8 +24,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[]; let x = a.equalsShallow(b); >x : Symbol(x, Decl(bivariantInferences.ts, 9, 3)) ->a.equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20)) +>a.equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20)) >a : Symbol(a, Decl(bivariantInferences.ts, 6, 13)) ->equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20)) +>equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20)) >b : Symbol(b, Decl(bivariantInferences.ts, 7, 13)) diff --git a/tests/baselines/reference/bivariantInferences.types b/tests/baselines/reference/bivariantInferences.types index ac987cbddaca4..7ad35660c556f 100644 --- a/tests/baselines/reference/bivariantInferences.types +++ b/tests/baselines/reference/bivariantInferences.types @@ -19,8 +19,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[]; let x = a.equalsShallow(b); >x : boolean >a.equalsShallow(b) : boolean ->a.equalsShallow : ((this: readonly T[], other: readonly T[]) => boolean) | ((this: readonly T[], other: readonly T[]) => boolean) | ((this: readonly T[], other: readonly T[]) => boolean) | ((this: readonly T[], other: readonly T[]) => boolean) +>a.equalsShallow : (this: readonly T[], other: readonly T[]) => boolean >a : (string | number)[] | null[] | undefined[] | {}[] ->equalsShallow : ((this: readonly T[], other: readonly T[]) => boolean) | ((this: readonly T[], other: readonly T[]) => boolean) | ((this: readonly T[], other: readonly T[]) => boolean) | ((this: readonly T[], other: readonly T[]) => boolean) +>equalsShallow : (this: readonly T[], other: readonly T[]) => boolean >b : (string | number)[] | null[] | undefined[] | {}[] diff --git a/tests/baselines/reference/checkOrderDependenceGenericAssignability.errors.txt b/tests/baselines/reference/checkOrderDependenceGenericAssignability.errors.txt new file mode 100644 index 0000000000000..448081e8daf19 --- /dev/null +++ b/tests/baselines/reference/checkOrderDependenceGenericAssignability.errors.txt @@ -0,0 +1,92 @@ +tests/cases/compiler/checkOrderDependenceGenericAssignability.ts(21,1): error TS2322: Type 'Parent1' is not assignable to type 'Parent1'. + Type 'unknown' is not assignable to type 'string'. +tests/cases/compiler/checkOrderDependenceGenericAssignability.ts(45,1): error TS2322: Type 'Parent2' is not assignable to type 'Parent2'. + Type 'unknown' is not assignable to type 'string'. +tests/cases/compiler/checkOrderDependenceGenericAssignability.ts(62,1): error TS2322: Type 'Child3' is not assignable to type 'Child3'. + Type 'unknown' is not assignable to type 'string'. +tests/cases/compiler/checkOrderDependenceGenericAssignability.ts(68,1): error TS2322: Type 'Parent3' is not assignable to type 'Parent3'. + Type 'unknown' is not assignable to type 'string'. + + +==== tests/cases/compiler/checkOrderDependenceGenericAssignability.ts (4 errors) ==== + // Repro from #44572 with interface types + + interface Parent1 { + child: Child1; + parent: Parent1; + } + + interface Child1 extends Parent1 { + readonly a: A; + readonly b: B; + } + + function fn1(inp: Child1) { + const a: Child1 = inp; + } + + declare let pu1: Parent1; + declare let ps1: Parent1; + + pu1 = ps1; // Ok + ps1 = pu1; // Error expected + ~~~ +!!! error TS2322: Type 'Parent1' is not assignable to type 'Parent1'. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + // Repro from #44572 with aliased object types + + type Parent2 = { + child: Child2; + parent: Parent2; + } + + type Child2 = { + child: Child2; + parent: Parent2; + readonly a: A; + readonly b: B; + } + + function fn2(inp: Child2) { + const a: Child2 = inp; + } + + declare let pu2: Parent2; + declare let ps2: Parent2; + + pu2 = ps2; // Ok + ps2 = pu2; // Error expected + ~~~ +!!! error TS2322: Type 'Parent2' is not assignable to type 'Parent2'. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + // Simpler repro for same issue + + interface Parent3 { + child: Child3; + parent: Parent3; + } + + interface Child3 extends Parent3 { + readonly a: A; + } + + declare let cu3: Child3; + declare let cs3: Child3; + + cu3 = cs3; // Ok + cs3 = cu3; // Error expected + ~~~ +!!! error TS2322: Type 'Child3' is not assignable to type 'Child3'. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + declare let pu3: Parent3; + declare let ps3: Parent3; + + pu3 = ps3; // Ok + ps3 = pu3; // Error expected + ~~~ +!!! error TS2322: Type 'Parent3' is not assignable to type 'Parent3'. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/checkOrderDependenceGenericAssignability.js b/tests/baselines/reference/checkOrderDependenceGenericAssignability.js new file mode 100644 index 0000000000000..c88526e85bf94 --- /dev/null +++ b/tests/baselines/reference/checkOrderDependenceGenericAssignability.js @@ -0,0 +1,88 @@ +//// [checkOrderDependenceGenericAssignability.ts] +// Repro from #44572 with interface types + +interface Parent1 { + child: Child1; + parent: Parent1; +} + +interface Child1 extends Parent1 { + readonly a: A; + readonly b: B; +} + +function fn1(inp: Child1) { + const a: Child1 = inp; +} + +declare let pu1: Parent1; +declare let ps1: Parent1; + +pu1 = ps1; // Ok +ps1 = pu1; // Error expected + +// Repro from #44572 with aliased object types + +type Parent2 = { + child: Child2; + parent: Parent2; +} + +type Child2 = { + child: Child2; + parent: Parent2; + readonly a: A; + readonly b: B; +} + +function fn2(inp: Child2) { + const a: Child2 = inp; +} + +declare let pu2: Parent2; +declare let ps2: Parent2; + +pu2 = ps2; // Ok +ps2 = pu2; // Error expected + +// Simpler repro for same issue + +interface Parent3 { + child: Child3; + parent: Parent3; +} + +interface Child3 extends Parent3 { + readonly a: A; +} + +declare let cu3: Child3; +declare let cs3: Child3; + +cu3 = cs3; // Ok +cs3 = cu3; // Error expected + +declare let pu3: Parent3; +declare let ps3: Parent3; + +pu3 = ps3; // Ok +ps3 = pu3; // Error expected + + +//// [checkOrderDependenceGenericAssignability.js] +"use strict"; +// Repro from #44572 with interface types +function fn1(inp) { + var a = inp; +} +pu1 = ps1; // Ok +ps1 = pu1; // Error expected +function fn2(inp) { + var a = inp; +} +pu2 = ps2; // Ok +ps2 = pu2; // Error expected +cu3 = cs3; // Ok +cs3 = cu3; // Error expected +pu3 = ps3; // Ok +ps3 = pu3; // Error expected diff --git a/tests/baselines/reference/checkOrderDependenceGenericAssignability.symbols b/tests/baselines/reference/checkOrderDependenceGenericAssignability.symbols new file mode 100644 index 0000000000000..8bbda87191438 --- /dev/null +++ b/tests/baselines/reference/checkOrderDependenceGenericAssignability.symbols @@ -0,0 +1,193 @@ +=== tests/cases/compiler/checkOrderDependenceGenericAssignability.ts === +// Repro from #44572 with interface types + +interface Parent1 { +>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 2, 18)) + + child: Child1; +>child : Symbol(Parent1.child, Decl(checkOrderDependenceGenericAssignability.ts, 2, 22)) +>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 2, 18)) + + parent: Parent1; +>parent : Symbol(Parent1.parent, Decl(checkOrderDependenceGenericAssignability.ts, 3, 21)) +>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 2, 18)) +} + +interface Child1 extends Parent1 { +>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 7, 17)) +>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 7, 19)) +>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 7, 17)) + + readonly a: A; +>a : Symbol(Child1.a, Decl(checkOrderDependenceGenericAssignability.ts, 7, 53)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 7, 17)) + + readonly b: B; +>b : Symbol(Child1.b, Decl(checkOrderDependenceGenericAssignability.ts, 8, 18)) +>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 7, 19)) +} + +function fn1(inp: Child1) { +>fn1 : Symbol(fn1, Decl(checkOrderDependenceGenericAssignability.ts, 10, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 12, 13)) +>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 12, 16)) +>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 12, 13)) + + const a: Child1 = inp; +>a : Symbol(a, Decl(checkOrderDependenceGenericAssignability.ts, 13, 9)) +>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1)) +>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 12, 16)) +} + +declare let pu1: Parent1; +>pu1 : Symbol(pu1, Decl(checkOrderDependenceGenericAssignability.ts, 16, 11)) +>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0)) + +declare let ps1: Parent1; +>ps1 : Symbol(ps1, Decl(checkOrderDependenceGenericAssignability.ts, 17, 11)) +>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0)) + +pu1 = ps1; // Ok +>pu1 : Symbol(pu1, Decl(checkOrderDependenceGenericAssignability.ts, 16, 11)) +>ps1 : Symbol(ps1, Decl(checkOrderDependenceGenericAssignability.ts, 17, 11)) + +ps1 = pu1; // Error expected +>ps1 : Symbol(ps1, Decl(checkOrderDependenceGenericAssignability.ts, 17, 11)) +>pu1 : Symbol(pu1, Decl(checkOrderDependenceGenericAssignability.ts, 16, 11)) + +// Repro from #44572 with aliased object types + +type Parent2 = { +>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 20, 10)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 24, 13)) + + child: Child2; +>child : Symbol(child, Decl(checkOrderDependenceGenericAssignability.ts, 24, 19)) +>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 27, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 24, 13)) + + parent: Parent2; +>parent : Symbol(parent, Decl(checkOrderDependenceGenericAssignability.ts, 25, 21)) +>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 20, 10)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 24, 13)) +} + +type Child2 = { +>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 27, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 29, 12)) +>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 29, 14)) + + child: Child2; +>child : Symbol(child, Decl(checkOrderDependenceGenericAssignability.ts, 29, 31)) +>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 27, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 29, 12)) + + parent: Parent2; +>parent : Symbol(parent, Decl(checkOrderDependenceGenericAssignability.ts, 30, 21)) +>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 20, 10)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 29, 12)) + + readonly a: A; +>a : Symbol(a, Decl(checkOrderDependenceGenericAssignability.ts, 31, 23)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 29, 12)) + + readonly b: B; +>b : Symbol(b, Decl(checkOrderDependenceGenericAssignability.ts, 32, 18)) +>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 29, 14)) +} + +function fn2(inp: Child2) { +>fn2 : Symbol(fn2, Decl(checkOrderDependenceGenericAssignability.ts, 34, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 36, 13)) +>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 36, 16)) +>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 27, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 36, 13)) + + const a: Child2 = inp; +>a : Symbol(a, Decl(checkOrderDependenceGenericAssignability.ts, 37, 9)) +>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 27, 1)) +>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 36, 16)) +} + +declare let pu2: Parent2; +>pu2 : Symbol(pu2, Decl(checkOrderDependenceGenericAssignability.ts, 40, 11)) +>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 20, 10)) + +declare let ps2: Parent2; +>ps2 : Symbol(ps2, Decl(checkOrderDependenceGenericAssignability.ts, 41, 11)) +>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 20, 10)) + +pu2 = ps2; // Ok +>pu2 : Symbol(pu2, Decl(checkOrderDependenceGenericAssignability.ts, 40, 11)) +>ps2 : Symbol(ps2, Decl(checkOrderDependenceGenericAssignability.ts, 41, 11)) + +ps2 = pu2; // Error expected +>ps2 : Symbol(ps2, Decl(checkOrderDependenceGenericAssignability.ts, 41, 11)) +>pu2 : Symbol(pu2, Decl(checkOrderDependenceGenericAssignability.ts, 40, 11)) + +// Simpler repro for same issue + +interface Parent3 { +>Parent3 : Symbol(Parent3, Decl(checkOrderDependenceGenericAssignability.ts, 44, 10)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 48, 18)) + + child: Child3; +>child : Symbol(Parent3.child, Decl(checkOrderDependenceGenericAssignability.ts, 48, 22)) +>Child3 : Symbol(Child3, Decl(checkOrderDependenceGenericAssignability.ts, 51, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 48, 18)) + + parent: Parent3; +>parent : Symbol(Parent3.parent, Decl(checkOrderDependenceGenericAssignability.ts, 49, 23)) +>Parent3 : Symbol(Parent3, Decl(checkOrderDependenceGenericAssignability.ts, 44, 10)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 48, 18)) +} + +interface Child3 extends Parent3 { +>Child3 : Symbol(Child3, Decl(checkOrderDependenceGenericAssignability.ts, 51, 1)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 53, 17)) +>Parent3 : Symbol(Parent3, Decl(checkOrderDependenceGenericAssignability.ts, 44, 10)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 53, 17)) + + readonly a: A; +>a : Symbol(Child3.a, Decl(checkOrderDependenceGenericAssignability.ts, 53, 40)) +>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 53, 17)) +} + +declare let cu3: Child3; +>cu3 : Symbol(cu3, Decl(checkOrderDependenceGenericAssignability.ts, 57, 11)) +>Child3 : Symbol(Child3, Decl(checkOrderDependenceGenericAssignability.ts, 51, 1)) + +declare let cs3: Child3; +>cs3 : Symbol(cs3, Decl(checkOrderDependenceGenericAssignability.ts, 58, 11)) +>Child3 : Symbol(Child3, Decl(checkOrderDependenceGenericAssignability.ts, 51, 1)) + +cu3 = cs3; // Ok +>cu3 : Symbol(cu3, Decl(checkOrderDependenceGenericAssignability.ts, 57, 11)) +>cs3 : Symbol(cs3, Decl(checkOrderDependenceGenericAssignability.ts, 58, 11)) + +cs3 = cu3; // Error expected +>cs3 : Symbol(cs3, Decl(checkOrderDependenceGenericAssignability.ts, 58, 11)) +>cu3 : Symbol(cu3, Decl(checkOrderDependenceGenericAssignability.ts, 57, 11)) + +declare let pu3: Parent3; +>pu3 : Symbol(pu3, Decl(checkOrderDependenceGenericAssignability.ts, 63, 11)) +>Parent3 : Symbol(Parent3, Decl(checkOrderDependenceGenericAssignability.ts, 44, 10)) + +declare let ps3: Parent3; +>ps3 : Symbol(ps3, Decl(checkOrderDependenceGenericAssignability.ts, 64, 11)) +>Parent3 : Symbol(Parent3, Decl(checkOrderDependenceGenericAssignability.ts, 44, 10)) + +pu3 = ps3; // Ok +>pu3 : Symbol(pu3, Decl(checkOrderDependenceGenericAssignability.ts, 63, 11)) +>ps3 : Symbol(ps3, Decl(checkOrderDependenceGenericAssignability.ts, 64, 11)) + +ps3 = pu3; // Error expected +>ps3 : Symbol(ps3, Decl(checkOrderDependenceGenericAssignability.ts, 64, 11)) +>pu3 : Symbol(pu3, Decl(checkOrderDependenceGenericAssignability.ts, 63, 11)) + diff --git a/tests/baselines/reference/checkOrderDependenceGenericAssignability.types b/tests/baselines/reference/checkOrderDependenceGenericAssignability.types new file mode 100644 index 0000000000000..afe81326fbcd3 --- /dev/null +++ b/tests/baselines/reference/checkOrderDependenceGenericAssignability.types @@ -0,0 +1,144 @@ +=== tests/cases/compiler/checkOrderDependenceGenericAssignability.ts === +// Repro from #44572 with interface types + +interface Parent1 { + child: Child1; +>child : Child1 + + parent: Parent1; +>parent : Parent1 +} + +interface Child1 extends Parent1 { + readonly a: A; +>a : A + + readonly b: B; +>b : B +} + +function fn1(inp: Child1) { +>fn1 : (inp: Child1) => void +>inp : Child1 + + const a: Child1 = inp; +>a : Child1 +>inp : Child1 +} + +declare let pu1: Parent1; +>pu1 : Parent1 + +declare let ps1: Parent1; +>ps1 : Parent1 + +pu1 = ps1; // Ok +>pu1 = ps1 : Parent1 +>pu1 : Parent1 +>ps1 : Parent1 + +ps1 = pu1; // Error expected +>ps1 = pu1 : Parent1 +>ps1 : Parent1 +>pu1 : Parent1 + +// Repro from #44572 with aliased object types + +type Parent2 = { +>Parent2 : Parent2 + + child: Child2; +>child : Child2 + + parent: Parent2; +>parent : Parent2 +} + +type Child2 = { +>Child2 : Child2 + + child: Child2; +>child : Child2 + + parent: Parent2; +>parent : Parent2 + + readonly a: A; +>a : A + + readonly b: B; +>b : B +} + +function fn2(inp: Child2) { +>fn2 : (inp: Child2) => void +>inp : Child2 + + const a: Child2 = inp; +>a : Child2 +>inp : Child2 +} + +declare let pu2: Parent2; +>pu2 : Parent2 + +declare let ps2: Parent2; +>ps2 : Parent2 + +pu2 = ps2; // Ok +>pu2 = ps2 : Parent2 +>pu2 : Parent2 +>ps2 : Parent2 + +ps2 = pu2; // Error expected +>ps2 = pu2 : Parent2 +>ps2 : Parent2 +>pu2 : Parent2 + +// Simpler repro for same issue + +interface Parent3 { + child: Child3; +>child : Child3 + + parent: Parent3; +>parent : Parent3 +} + +interface Child3 extends Parent3 { + readonly a: A; +>a : A +} + +declare let cu3: Child3; +>cu3 : Child3 + +declare let cs3: Child3; +>cs3 : Child3 + +cu3 = cs3; // Ok +>cu3 = cs3 : Child3 +>cu3 : Child3 +>cs3 : Child3 + +cs3 = cu3; // Error expected +>cs3 = cu3 : Child3 +>cs3 : Child3 +>cu3 : Child3 + +declare let pu3: Parent3; +>pu3 : Parent3 + +declare let ps3: Parent3; +>ps3 : Parent3 + +pu3 = ps3; // Ok +>pu3 = ps3 : Parent3 +>pu3 : Parent3 +>ps3 : Parent3 + +ps3 = pu3; // Error expected +>ps3 = pu3 : Parent3 +>ps3 : Parent3 +>pu3 : Parent3 + diff --git a/tests/baselines/reference/completionEntryForUnionMethod.baseline b/tests/baselines/reference/completionEntryForUnionMethod.baseline index f03ee666dc0d8..888c5b3c2787d 100644 --- a/tests/baselines/reference/completionEntryForUnionMethod.baseline +++ b/tests/baselines/reference/completionEntryForUnionMethod.baseline @@ -2244,7 +2244,7 @@ }, { "text": "join", - "kind": "propertyName" + "kind": "methodName" }, { "text": "(", @@ -5906,7 +5906,7 @@ }, { "text": "toLocaleString", - "kind": "propertyName" + "kind": "methodName" }, { "text": "(", @@ -5980,7 +5980,7 @@ }, { "text": "toString", - "kind": "propertyName" + "kind": "methodName" }, { "text": "(", diff --git a/tests/baselines/reference/sliceResultCast.symbols b/tests/baselines/reference/sliceResultCast.symbols index 5fed27ca3fd5c..0f8a4761baaa4 100644 --- a/tests/baselines/reference/sliceResultCast.symbols +++ b/tests/baselines/reference/sliceResultCast.symbols @@ -3,7 +3,7 @@ declare var x: [number, string] | [number, string, string]; >x : Symbol(x, Decl(sliceResultCast.ts, 0, 11)) x.slice(1) as readonly string[]; ->x.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>x.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(sliceResultCast.ts, 0, 11)) ->slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/sliceResultCast.types b/tests/baselines/reference/sliceResultCast.types index 99f799f27ff38..221046e037d96 100644 --- a/tests/baselines/reference/sliceResultCast.types +++ b/tests/baselines/reference/sliceResultCast.types @@ -5,8 +5,8 @@ declare var x: [number, string] | [number, string, string]; x.slice(1) as readonly string[]; >x.slice(1) as readonly string[] : readonly string[] >x.slice(1) : (string | number)[] ->x.slice : ((start?: number, end?: number) => (string | number)[]) | ((start?: number, end?: number) => (string | number)[]) +>x.slice : (start?: number, end?: number) => (string | number)[] >x : [number, string] | [number, string, string] ->slice : ((start?: number, end?: number) => (string | number)[]) | ((start?: number, end?: number) => (string | number)[]) +>slice : (start?: number, end?: number) => (string | number)[] >1 : 1 diff --git a/tests/baselines/reference/tsxUnionElementType3.errors.txt b/tests/baselines/reference/tsxUnionElementType3.errors.txt index 73d8ccb0ce2b2..1474b9fb77490 100644 --- a/tests/baselines/reference/tsxUnionElementType3.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType3.errors.txt @@ -36,7 +36,7 @@ tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not let a = ; ~ !!! error TS2322: Type 'string' is not assignable to type 'never'. -!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' +!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; }' let a1 = ; let a2 = ; let b = diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index 03cb6c62a526e..7f2b4bca54211 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -40,7 +40,7 @@ tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; } let a = ; ~ !!! error TS2322: Type 'boolean' is not assignable to type 'never'. -!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' +!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; }' let b = ~ !!! error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. diff --git a/tests/baselines/reference/varianceMeasurement.errors.txt b/tests/baselines/reference/varianceMeasurement.errors.txt index 4deb2d81e0b64..e65e8c1936881 100644 --- a/tests/baselines/reference/varianceMeasurement.errors.txt +++ b/tests/baselines/reference/varianceMeasurement.errors.txt @@ -1,5 +1,9 @@ tests/cases/compiler/varianceMeasurement.ts(10,7): error TS2322: Type 'Foo1' is not assignable to type 'Foo1<"a">'. - Type 'string' is not assignable to type '"a"'. + Types of property 'x' are incompatible. + Type 'string' is not assignable to type '"a"'. +tests/cases/compiler/varianceMeasurement.ts(11,7): error TS2322: Type 'Foo1' is not assignable to type 'Foo1'. + The types of 'y.x' are incompatible between these types. + Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. tests/cases/compiler/varianceMeasurement.ts(21,7): error TS2322: Type 'Foo2' is not assignable to type 'Foo2<"a">'. Types of property 'x' are incompatible. Type 'string' is not assignable to type '"a"'. @@ -9,7 +13,11 @@ tests/cases/compiler/varianceMeasurement.ts(22,7): error TS2322: Type 'Foo2' is not assignable to type 'Foo3<"a">'. - Type 'string' is not assignable to type '"a"'. + Types of property 'x' are incompatible. + Type 'string' is not assignable to type '"a"'. +tests/cases/compiler/varianceMeasurement.ts(34,7): error TS2322: Type 'Foo3' is not assignable to type 'Foo3'. + The types of 'y.x' are incompatible between these types. + Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. tests/cases/compiler/varianceMeasurement.ts(44,7): error TS2322: Type 'Foo4' is not assignable to type 'Foo4<"a">'. Types of property 'x' are incompatible. Type 'string' is not assignable to type '"a"'. @@ -26,7 +34,7 @@ tests/cases/compiler/varianceMeasurement.ts(75,7): error TS2322: Type 'C = f10; ~~~ !!! error TS2322: Type 'Foo1' is not assignable to type 'Foo1<"a">'. -!!! error TS2322: Type 'string' is not assignable to type '"a"'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type '"a"'. const f12: Foo1 = f10; + ~~~ +!!! error TS2322: Type 'Foo1' is not assignable to type 'Foo1'. +!!! error TS2322: The types of 'y.x' are incompatible between these types. +!!! error TS2322: Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. // The type below is invariant in T and is measured as such. @@ -75,8 +88,13 @@ tests/cases/compiler/varianceMeasurement.ts(75,7): error TS2322: Type 'C = f30; ~~~ !!! error TS2322: Type 'Foo3' is not assignable to type 'Foo3<"a">'. -!!! error TS2322: Type 'string' is not assignable to type '"a"'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type '"a"'. const f32: Foo3 = f30; + ~~~ +!!! error TS2322: Type 'Foo3' is not assignable to type 'Foo3'. +!!! error TS2322: The types of 'y.x' are incompatible between these types. +!!! error TS2322: Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. // The type below is invariant in T and is measured as such. diff --git a/tests/cases/compiler/checkOrderDependenceGenericAssignability.ts b/tests/cases/compiler/checkOrderDependenceGenericAssignability.ts new file mode 100644 index 0000000000000..b4701ed36dc3b --- /dev/null +++ b/tests/cases/compiler/checkOrderDependenceGenericAssignability.ts @@ -0,0 +1,70 @@ +// @strict: true + +// Repro from #44572 with interface types + +interface Parent1 { + child: Child1; + parent: Parent1; +} + +interface Child1 extends Parent1 { + readonly a: A; + readonly b: B; +} + +function fn1(inp: Child1) { + const a: Child1 = inp; +} + +declare let pu1: Parent1; +declare let ps1: Parent1; + +pu1 = ps1; // Ok +ps1 = pu1; // Error expected + +// Repro from #44572 with aliased object types + +type Parent2 = { + child: Child2; + parent: Parent2; +} + +type Child2 = { + child: Child2; + parent: Parent2; + readonly a: A; + readonly b: B; +} + +function fn2(inp: Child2) { + const a: Child2 = inp; +} + +declare let pu2: Parent2; +declare let ps2: Parent2; + +pu2 = ps2; // Ok +ps2 = pu2; // Error expected + +// Simpler repro for same issue + +interface Parent3 { + child: Child3; + parent: Parent3; +} + +interface Child3 extends Parent3 { + readonly a: A; +} + +declare let cu3: Child3; +declare let cs3: Child3; + +cu3 = cs3; // Ok +cs3 = cu3; // Error expected + +declare let pu3: Parent3; +declare let ps3: Parent3; + +pu3 = ps3; // Ok +ps3 = pu3; // Error expected