Skip to content

Commit 8f6e626

Browse files
authored
Permit type alias variance annotations only for certain object types (#48589)
* Permit type alias variance annotations only for certain object types * Accept new baselines
1 parent 3fd8a6e commit 8f6e626

File tree

4 files changed

+54
-16
lines changed

4 files changed

+54
-16
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34795,14 +34795,19 @@ namespace ts {
3479534795
}
3479634796
if (node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.ClassDeclaration || node.parent.kind === SyntaxKind.TypeAliasDeclaration) {
3479734797
const modifiers = getVarianceModifiers(typeParameter);
34798-
if (modifiers === ModifierFlags.In || modifiers === ModifierFlags.Out) {
34798+
if (modifiers) {
3479934799
const symbol = getSymbolOfNode(node.parent);
34800-
const source = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSubType : markerSuperType);
34801-
const target = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSuperType : markerSubType);
34802-
const saveVarianceTypeParameter = typeParameter;
34803-
varianceTypeParameter = typeParameter;
34804-
checkTypeAssignableTo(source, target, node, Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation);
34805-
varianceTypeParameter = saveVarianceTypeParameter;
34800+
if (node.parent.kind === SyntaxKind.TypeAliasDeclaration && !(getObjectFlags(getDeclaredTypeOfSymbol(symbol)) & (ObjectFlags.Anonymous | ObjectFlags.Mapped))) {
34801+
error(node, Diagnostics.Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_types);
34802+
}
34803+
else if (modifiers === ModifierFlags.In || modifiers === ModifierFlags.Out) {
34804+
const source = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSubType : markerSuperType);
34805+
const target = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSuperType : markerSubType);
34806+
const saveVarianceTypeParameter = typeParameter;
34807+
varianceTypeParameter = typeParameter;
34808+
checkTypeAssignableTo(source, target, node, Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation);
34809+
varianceTypeParameter = saveVarianceTypeParameter;
34810+
}
3480634811
}
3480734812
}
3480834813
addLazyDiagnostic(() => checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0));

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,10 @@
27432743
"category": "Error",
27442744
"code": 2636
27452745
},
2746+
"Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.": {
2747+
"category": "Error",
2748+
"code": 2637
2749+
},
27462750

27472751
"Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": {
27482752
"category": "Error",

tests/baselines/reference/varianceAnnotations.errors.txt

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati
1010
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(29,1): error TS2322: Type 'Invariant<unknown>' is not assignable to type 'Invariant<string>'.
1111
The types returned by 'f(...)' are incompatible between these types.
1212
Type 'unknown' is not assignable to type 'string'.
13+
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.
14+
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.
15+
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.
16+
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.
17+
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.
1318
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(40,17): error TS2636: Type 'Covariant1<super-T>' is not assignable to type 'Covariant1<sub-T>' as implied by variance annotation.
1419
Types of property 'x' are incompatible.
1520
Type 'super-T' is not assignable to type 'sub-T'.
16-
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.
17-
Type 'string | number | symbol' is not assignable to type 'keyof super-T'.
18-
Type 'string' is not assignable to type 'keyof super-T'.
21+
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.
1922
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(46,21): error TS2636: Type 'Contravariant2<sub-T>' is not assignable to type 'Contravariant2<super-T>' as implied by variance annotation.
2023
Types of property 'f' are incompatible.
2124
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
3740
Type 'FooFn2<sub-T>' is not assignable to type 'FooFn2<super-T>'.
3841
Type 'super-T' is not assignable to type 'sub-T'.
3942
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(95,10): error TS1273: 'public' modifier cannot appear on a type parameter
43+
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.
4044
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(96,17): error TS1030: 'in' modifier already seen.
45+
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.
4146
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(97,17): error TS1030: 'out' modifier already seen.
47+
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.
4248
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts(98,14): error TS1029: 'in' modifier must precede 'out' modifier.
4349
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
4450
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
6066
Type '{ type: "RESET"; }' is not assignable to type '{ type: "PLAY"; value: number; }'.
6167

6268

63-
==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts (23 errors) ====
69+
==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts (31 errors) ====
6470
type Covariant<out T> = {
6571
x: T;
6672
}
@@ -110,9 +116,19 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati
110116
// Variance of various type constructors
111117

112118
type T10<out T> = T;
119+
~~~~~
120+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
113121
type T11<in T> = keyof T;
122+
~~~~
123+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
114124
type T12<out T, out K extends keyof T> = T[K];
125+
~~~~~
126+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
127+
~~~~~~~~~~~~~~~~~~~~~
128+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
115129
type T13<in out T> = T[keyof T];
130+
~~~~~~~~
131+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
116132

117133
// Variance annotation errors
118134

@@ -126,9 +142,7 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati
126142

127143
type Contravariant1<out T> = keyof T; // Error
128144
~~~~~
129-
!!! error TS2636: Type 'keyof sub-T' is not assignable to type 'keyof super-T' as implied by variance annotation.
130-
!!! error TS2636: Type 'string | number | symbol' is not assignable to type 'keyof super-T'.
131-
!!! error TS2636: Type 'string' is not assignable to type 'keyof super-T'.
145+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
132146

133147
type Contravariant2<out T> = { // Error
134148
~~~~~
@@ -208,12 +222,18 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotati
208222
~~~~~~
209223
!!! error TS1273: 'public' modifier cannot appear on a type parameter
210224
type T21<in out in T> = T; // Error
225+
~~~~~~~~~~~
226+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
211227
~~
212228
!!! error TS1030: 'in' modifier already seen.
213229
type T22<in out out T> = T; // Error
230+
~~~~~~~~~~~~
231+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
214232
~~~
215233
!!! error TS1030: 'out' modifier already seen.
216234
type T23<out in T> = T; // Error
235+
~~~~~~~~
236+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
217237
~~
218238
!!! error TS1029: 'in' modifier must precede 'out' modifier.
219239

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,6): error TS2456: Type alias 'T1' circularly references itself.
2+
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.
23
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,11): error TS2300: Duplicate identifier '(Missing)'.
4+
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.
35
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(1,12): error TS1359: Identifier expected. 'in' is a reserved word that cannot be used here.
46
tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts(2,6): error TS2456: Type alias 'T2' circularly references itself.
7+
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.
58

69

7-
==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts (4 errors) ====
10+
==== tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotationsWithCircularlyReferencesError.ts (7 errors) ====
811
type T1<in in> = T1 // Error: circularly references
912
~~
1013
!!! error TS2456: Type alias 'T1' circularly references itself.
14+
~~
15+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
1116

1217
!!! error TS2300: Duplicate identifier '(Missing)'.
18+
19+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.
1320
~~
1421
!!! error TS1359: Identifier expected. 'in' is a reserved word that cannot be used here.
1522
type T2<out out> = T2 // Error: circularly references
1623
~~
17-
!!! error TS2456: Type alias 'T2' circularly references itself.
24+
!!! error TS2456: Type alias 'T2' circularly references itself.
25+
~~~~~~~
26+
!!! error TS2637: Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.

0 commit comments

Comments
 (0)