diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4fb6b55412e02..e0c31788104d9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34795,14 +34795,19 @@ namespace ts { } if (node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.ClassDeclaration || node.parent.kind === SyntaxKind.TypeAliasDeclaration) { const modifiers = getVarianceModifiers(typeParameter); - if (modifiers === ModifierFlags.In || modifiers === ModifierFlags.Out) { + if (modifiers) { const symbol = getSymbolOfNode(node.parent); - const source = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSubType : markerSuperType); - const target = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSuperType : markerSubType); - const saveVarianceTypeParameter = typeParameter; - varianceTypeParameter = typeParameter; - checkTypeAssignableTo(source, target, node, Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation); - varianceTypeParameter = saveVarianceTypeParameter; + if (node.parent.kind === SyntaxKind.TypeAliasDeclaration && !(getObjectFlags(getDeclaredTypeOfSymbol(symbol)) & (ObjectFlags.Anonymous | ObjectFlags.Mapped))) { + error(node, Diagnostics.Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_types); + } + else if (modifiers === ModifierFlags.In || modifiers === ModifierFlags.Out) { + const source = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSubType : markerSuperType); + const target = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSuperType : markerSubType); + const saveVarianceTypeParameter = typeParameter; + varianceTypeParameter = typeParameter; + checkTypeAssignableTo(source, target, node, Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation); + varianceTypeParameter = saveVarianceTypeParameter; + } } } addLazyDiagnostic(() => checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0)); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3bc61d247ace5..e8a765e514cb5 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2743,6 +2743,10 @@ "category": "Error", "code": 2636 }, + "Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.": { + "category": "Error", + "code": 2637 + }, "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { "category": "Error", diff --git a/tests/baselines/reference/varianceAnnotations.errors.txt b/tests/baselines/reference/varianceAnnotations.errors.txt index f1be2f615bb34..5cd036e723471 100644 --- a/tests/baselines/reference/varianceAnnotations.errors.txt +++ b/tests/baselines/reference/varianceAnnotations.errors.txt @@ -10,12 +10,15 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(29,1): error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. The types returned by 'f(...)' are incompatible between these types. Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(33,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(34,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(35,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(35,17): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(36,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(40,17): error TS2636: Type 'Covariant1' is not assignable to type 'Covariant1' as implied by variance annotation. Types of property 'x' are incompatible. Type 'super-T' is not assignable to type 'sub-T'. -tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(44,21): error TS2636: Type 'keyof sub-T' is not assignable to type 'keyof super-T' as implied by variance annotation. - Type 'string | number | symbol' is not assignable to type 'keyof super-T'. - Type 'string' is not assignable to type 'keyof super-T'. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(44,21): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(46,21): error TS2636: Type 'Contravariant2' is not assignable to type 'Contravariant2' as implied by variance annotation. Types of property 'f' are incompatible. Type '(x: sub-T) => void' is not assignable to type '(x: super-T) => void'. @@ -37,8 +40,11 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati Type 'FooFn2' is not assignable to type 'FooFn2'. Type 'super-T' is not assignable to type 'sub-T'. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(95,10): error TS1273: 'public' modifier cannot appear on a type parameter +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(96,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(96,17): error TS1030: 'in' modifier already seen. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(97,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(97,17): error TS1030: 'out' modifier already seen. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(98,10): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(98,14): error TS1029: 'in' modifier must precede 'out' modifier. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(100,21): error TS1274: 'in' modifier can only appear on a type parameter of a class, interface or type alias tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(101,21): error TS1274: 'out' modifier can only appear on a type parameter of a class, interface or type alias @@ -60,7 +66,7 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati Type '{ type: "RESET"; }' is not assignable to type '{ type: "PLAY"; value: number; }'. -==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts (23 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts (31 errors) ==== type Covariant = { x: T; } @@ -110,9 +116,19 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati // Variance of various type constructors type T10 = T; + ~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. type T11 = keyof T; + ~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. type T12 = T[K]; + ~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. type T13 = T[keyof T]; + ~~~~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. // Variance annotation errors @@ -126,9 +142,7 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati type Contravariant1 = keyof T; // Error ~~~~~ -!!! error TS2636: Type 'keyof sub-T' is not assignable to type 'keyof super-T' as implied by variance annotation. -!!! error TS2636: Type 'string | number | symbol' is not assignable to type 'keyof super-T'. -!!! error TS2636: Type 'string' is not assignable to type 'keyof super-T'. +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. type Contravariant2 = { // Error ~~~~~ @@ -208,12 +222,18 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati ~~~~~~ !!! error TS1273: 'public' modifier cannot appear on a type parameter type T21 = T; // Error + ~~~~~~~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. ~~ !!! error TS1030: 'in' modifier already seen. type T22 = T; // Error + ~~~~~~~~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. ~~~ !!! error TS1030: 'out' modifier already seen. type T23 = T; // Error + ~~~~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. ~~ !!! error TS1029: 'in' modifier must precede 'out' modifier. diff --git a/tests/baselines/reference/varianceAnnotationsWithCircularlyReferencesError.errors.txt b/tests/baselines/reference/varianceAnnotationsWithCircularlyReferencesError.errors.txt index d65890519677a..14d77a1e5db22 100644 --- a/tests/baselines/reference/varianceAnnotationsWithCircularlyReferencesError.errors.txt +++ b/tests/baselines/reference/varianceAnnotationsWithCircularlyReferencesError.errors.txt @@ -1,17 +1,26 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,6): error TS2456: Type alias 'T1' circularly references itself. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,9): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,11): error TS2300: Duplicate identifier '(Missing)'. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,11): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,12): error TS1359: Identifier expected. 'in' is a reserved word that cannot be used here. tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(2,6): error TS2456: Type alias 'T2' circularly references itself. +tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(2,9): error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. -==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts (4 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts (7 errors) ==== type T1 = T1 // Error: circularly references ~~ !!! error TS2456: Type alias 'T1' circularly references itself. + ~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. !!! error TS2300: Duplicate identifier '(Missing)'. + +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. ~~ !!! error TS1359: Identifier expected. 'in' is a reserved word that cannot be used here. type T2 = T2 // Error: circularly references ~~ -!!! error TS2456: Type alias 'T2' circularly references itself. \ No newline at end of file +!!! error TS2456: Type alias 'T2' circularly references itself. + ~~~~~~~ +!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types. \ No newline at end of file