diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 48bc0da113816..486ad7ca0c8e1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31886,7 +31886,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getContextualTypeForStaticPropertyDeclaration(declaration: PropertyDeclaration, contextFlags: ContextFlags | undefined): Type | undefined { const parentType = isExpression(declaration.parent) && getContextualType(declaration.parent, contextFlags); - if (!parentType) return undefined; + // Avoid spurious circularities caused by trying to contextually type a static property with an in-progress type using its own (still potentially unresolved) type + if (!parentType || parentType.symbol?.valueDeclaration === declaration.parent) return undefined; return getTypeOfPropertyOfContextualType(parentType, getSymbolOfDeclaration(declaration).escapedName); } diff --git a/tests/baselines/reference/classStaticPropertyNoSpuriousCircularityError1.symbols b/tests/baselines/reference/classStaticPropertyNoSpuriousCircularityError1.symbols new file mode 100644 index 0000000000000..7a87c28f4cbaa --- /dev/null +++ b/tests/baselines/reference/classStaticPropertyNoSpuriousCircularityError1.symbols @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts] //// + +=== classStaticPropertyNoSpuriousCircularityError1.ts === +// https://github.com/microsoft/TypeScript/issues/62552 + +function id(x: T): T { +>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0)) +>T : Symbol(T, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 12)) +>x : Symbol(x, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 15)) +>T : Symbol(T, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 12)) +>T : Symbol(T, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 12)) + + return x +>x : Symbol(x, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 15)) +} + +const Foo = id(class { +>Foo : Symbol(Foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 5)) +>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0)) + + static readonly foo = id(42) // ok +>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 22)) +>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0)) + +}) + +Foo.foo // 42 +>Foo.foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 22)) +>Foo : Symbol(Foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 5)) +>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 22)) + +const Foo2 = id(class { +>Foo2 : Symbol(Foo2, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 5)) +>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0)) + + static foo = id(42) // ok +>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 23)) +>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0)) + +}) + +Foo2.foo // number +>Foo2.foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 23)) +>Foo2 : Symbol(Foo2, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 5)) +>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 23)) + diff --git a/tests/baselines/reference/classStaticPropertyNoSpuriousCircularityError1.types b/tests/baselines/reference/classStaticPropertyNoSpuriousCircularityError1.types new file mode 100644 index 0000000000000..20f83cd7fcbf2 --- /dev/null +++ b/tests/baselines/reference/classStaticPropertyNoSpuriousCircularityError1.types @@ -0,0 +1,76 @@ +//// [tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts] //// + +=== classStaticPropertyNoSpuriousCircularityError1.ts === +// https://github.com/microsoft/TypeScript/issues/62552 + +function id(x: T): T { +>id : (x: T) => T +> : ^ ^^ ^^ ^^^^^ +>x : T +> : ^ + + return x +>x : T +> : ^ +} + +const Foo = id(class { +>Foo : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>id(class { static readonly foo = id(42) // ok}) : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>id : (x: T) => T +> : ^ ^^ ^^ ^^^^^ +>class { static readonly foo = id(42) // ok} : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ + + static readonly foo = id(42) // ok +>foo : 42 +> : ^^ +>id(42) : 42 +> : ^^ +>id : (x: T) => T +> : ^ ^^ ^^ ^^^^^ +>42 : 42 +> : ^^ + +}) + +Foo.foo // 42 +>Foo.foo : 42 +> : ^^ +>Foo : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>foo : 42 +> : ^^ + +const Foo2 = id(class { +>Foo2 : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>id(class { static foo = id(42) // ok}) : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>id : (x: T) => T +> : ^ ^^ ^^ ^^^^^ +>class { static foo = id(42) // ok} : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ + + static foo = id(42) // ok +>foo : number +> : ^^^^^^ +>id(42) : 42 +> : ^^ +>id : (x: T) => T +> : ^ ^^ ^^ ^^^^^ +>42 : 42 +> : ^^ + +}) + +Foo2.foo // number +>Foo2.foo : number +> : ^^^^^^ +>Foo2 : typeof (Anonymous class) +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>foo : number +> : ^^^^^^ + diff --git a/tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts b/tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts new file mode 100644 index 0000000000000..85e5edb62ad5e --- /dev/null +++ b/tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts @@ -0,0 +1,20 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62552 + +function id(x: T): T { + return x +} + +const Foo = id(class { + static readonly foo = id(42) // ok +}) + +Foo.foo // 42 + +const Foo2 = id(class { + static foo = id(42) // ok +}) + +Foo2.foo // number