diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4b8d44e62fc9f..7b414bd18ebf6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -41494,7 +41494,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function checkClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration) { + function checkClassStaticBlockDeclarationDeferred(node: ClassStaticBlockDeclaration) { checkGrammarModifiers(node); forEachChild(node, checkSourceElement); @@ -47937,7 +47937,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.MethodSignature: return checkMethodDeclaration(node as MethodDeclaration | MethodSignature); case SyntaxKind.ClassStaticBlockDeclaration: - return checkClassStaticBlockDeclaration(node as ClassStaticBlockDeclaration); + return checkNodeDeferred(node); case SyntaxKind.Constructor: return checkConstructorDeclaration(node as ConstructorDeclaration); case SyntaxKind.GetAccessor: @@ -48248,6 +48248,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.MethodSignature: checkFunctionExpressionOrObjectLiteralMethodDeferred(node as FunctionExpression); break; + case SyntaxKind.ClassStaticBlockDeclaration: + checkClassStaticBlockDeclarationDeferred(node as ClassStaticBlockDeclaration); + break; case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: checkAccessorDeclaration(node as AccessorDeclaration); diff --git a/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.errors.txt b/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.errors.txt new file mode 100644 index 0000000000000..7419505e09991 --- /dev/null +++ b/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.errors.txt @@ -0,0 +1,41 @@ +classStaticBlockDoNotSpoilVariance1.ts(7,35): error TS2344: Type 'A' does not satisfy the constraint 'A'. + Type 'T' is not assignable to type 'number'. +classStaticBlockDoNotSpoilVariance1.ts(20,36): error TS2344: Type 'A2' does not satisfy the constraint 'A2'. + Type 'T' is not assignable to type 'number'. + + +==== classStaticBlockDoNotSpoilVariance1.ts (2 errors) ==== + class A { + static { + type _ = T; + } + + value!: T; + child!: InstanceType>>; + ~~~~ +!!! error TS2344: Type 'A' does not satisfy the constraint 'A'. +!!! error TS2344: Type 'T' is not assignable to type 'number'. +!!! related TS2208 classStaticBlockDoNotSpoilVariance1.ts:1:9: This type parameter might need an `extends number` constraint. + + static B = class B { + parent!: T; + }; + } + + const A2 = class A2 { + static { + type _ = T; + } + + value!: T; + child!: InstanceType>>; + ~~~~~ +!!! error TS2344: Type 'A2' does not satisfy the constraint 'A2'. +!!! error TS2344: Type 'T' is not assignable to type 'number'. +!!! related TS2208 classStaticBlockDoNotSpoilVariance1.ts:14:21: This type parameter might need an `extends number` constraint. + + static B = class B { + parent!: T; + }; + }; + \ No newline at end of file diff --git a/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.symbols b/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.symbols new file mode 100644 index 0000000000000..f587eebcfcb63 --- /dev/null +++ b/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.symbols @@ -0,0 +1,84 @@ +//// [tests/cases/conformance/classes/classStaticBlock/classStaticBlockDoNotSpoilVariance1.ts] //// + +=== classStaticBlockDoNotSpoilVariance1.ts === +class A { +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 8)) + + static { + type _ = T; +>_ : Symbol(_, Decl(classStaticBlockDoNotSpoilVariance1.ts, 1, 10)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 2, 11)) +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 2, 11)) + } + + value!: T; +>value : Symbol(A.value, Decl(classStaticBlockDoNotSpoilVariance1.ts, 3, 3)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 8)) + + child!: InstanceType>>; +>child : Symbol(A.child, Decl(classStaticBlockDoNotSpoilVariance1.ts, 5, 12)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>A.B : Symbol(A.B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 6, 41)) +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) +>B : Symbol(A.B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 6, 41)) +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 8)) + + static B = class B { +>B : Symbol(A.B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 6, 41)) +>B : Symbol(B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 8, 12)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 8, 21)) +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) +>A : Symbol(A, Decl(classStaticBlockDoNotSpoilVariance1.ts, 0, 0)) + + parent!: T; +>parent : Symbol(B.parent, Decl(classStaticBlockDoNotSpoilVariance1.ts, 8, 39)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 8, 21)) + + }; +} + +const A2 = class A2 { +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 5)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 20)) + + static { + type _ = T; +>_ : Symbol(_, Decl(classStaticBlockDoNotSpoilVariance1.ts, 14, 10)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 15, 11)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 15, 11)) + } + + value!: T; +>value : Symbol(A2.value, Decl(classStaticBlockDoNotSpoilVariance1.ts, 16, 3)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 20)) + + child!: InstanceType>>; +>child : Symbol(A2.child, Decl(classStaticBlockDoNotSpoilVariance1.ts, 18, 12)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>A2.B : Symbol(A2.B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 19, 43)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) +>B : Symbol(A2.B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 19, 43)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 20)) + + static B = class B { +>B : Symbol(A2.B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 19, 43)) +>B : Symbol(B, Decl(classStaticBlockDoNotSpoilVariance1.ts, 21, 12)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 21, 21)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) +>A2 : Symbol(A2, Decl(classStaticBlockDoNotSpoilVariance1.ts, 13, 10)) + + parent!: T; +>parent : Symbol(B.parent, Decl(classStaticBlockDoNotSpoilVariance1.ts, 21, 41)) +>T : Symbol(T, Decl(classStaticBlockDoNotSpoilVariance1.ts, 21, 21)) + + }; +}; + diff --git a/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.types b/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.types new file mode 100644 index 0000000000000..bf1c8eb4b0013 --- /dev/null +++ b/tests/baselines/reference/classStaticBlockDoNotSpoilVariance1.types @@ -0,0 +1,85 @@ +//// [tests/cases/conformance/classes/classStaticBlock/classStaticBlockDoNotSpoilVariance1.ts] //// + +=== classStaticBlockDoNotSpoilVariance1.ts === +class A { +>A : A +> : ^^^^ + + static { + type _ = T; +>_ : T +> : ^ + } + + value!: T; +>value : T +> : ^ + + child!: InstanceType>>; +>child : B> +> : ^^^^^^^ +>A.B : typeof B +> : ^^^^^^^^ +>A : typeof A +> : ^^^^^^^^ +>B : typeof B +> : ^^^^^^^^ + + static B = class B { +>B : typeof B +> : ^^^^^^^^ +>class B { parent!: T; } : typeof B +> : ^^^^^^^^ +>B : typeof B +> : ^^^^^^^^ + + parent!: T; +>parent : T +> : ^ + + }; +} + +const A2 = class A2 { +>A2 : typeof A2 +> : ^^^^^^^^^ +>class A2 { static { type _ = T; } value!: T; child!: InstanceType>>; static B = class B { parent!: T; };} : typeof A2 +> : ^^^^^^^^^ +>A2 : typeof A2 +> : ^^^^^^^^^ + + static { + type _ = T; +>_ : T +> : ^ + } + + value!: T; +>value : T +> : ^ + + child!: InstanceType>>; +>child : B> +> : ^^^^^^^^ +>A2.B : typeof B +> : ^^^^^^^^ +>A2 : typeof A2 +> : ^^^^^^^^^ +>B : typeof B +> : ^^^^^^^^ + + static B = class B { +>B : typeof B +> : ^^^^^^^^ +>class B { parent!: T; } : typeof B +> : ^^^^^^^^ +>B : typeof B +> : ^^^^^^^^ + + parent!: T; +>parent : T +> : ^ + + }; +}; + diff --git a/tests/cases/conformance/classes/classStaticBlock/classStaticBlockDoNotSpoilVariance1.ts b/tests/cases/conformance/classes/classStaticBlock/classStaticBlockDoNotSpoilVariance1.ts new file mode 100644 index 0000000000000..9a925c0750d42 --- /dev/null +++ b/tests/cases/conformance/classes/classStaticBlock/classStaticBlockDoNotSpoilVariance1.ts @@ -0,0 +1,29 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +class A { + static { + type _ = T; + } + + value!: T; + child!: InstanceType>>; + + static B = class B { + parent!: T; + }; +} + +const A2 = class A2 { + static { + type _ = T; + } + + value!: T; + child!: InstanceType>>; + + static B = class B { + parent!: T; + }; +}; diff --git a/tests/cases/fourslash/quickInfoAvoidsClassVarianceCircularity1.ts b/tests/cases/fourslash/quickInfoAvoidsClassVarianceCircularity1.ts new file mode 100644 index 0000000000000..709532526b920 --- /dev/null +++ b/tests/cases/fourslash/quickInfoAvoidsClassVarianceCircularity1.ts @@ -0,0 +1,19 @@ +/// + +// @strict: true + +//// class A { +//// value!: T; +//// child!: InstanceType>>; +//// +//// static B = class B { +//// parent!: T; +//// }; +//// } +//// +//// var a = new A(); +//// +//// a.child.parent.value/**/; + +verify.quickInfoAt("", "(property) A.value: number"); +verify.getSemanticDiagnostics([]);