Skip to content

Commit e797862

Browse files
committed
Avoid an attempt to contextually type static property declaration using itself to avoid spurious circularity
1 parent fe592f1 commit e797862

File tree

4 files changed

+144
-1
lines changed

4 files changed

+144
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31886,7 +31886,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3188631886

3188731887
function getContextualTypeForStaticPropertyDeclaration(declaration: PropertyDeclaration, contextFlags: ContextFlags | undefined): Type | undefined {
3188831888
const parentType = isExpression(declaration.parent) && getContextualType(declaration.parent, contextFlags);
31889-
if (!parentType) return undefined;
31889+
// Avoid spurious circularities caused by trying to contextually type a static property with an in-progress type using its own (still potentially unresolved) type
31890+
if (!parentType || parentType.symbol?.valueDeclaration === declaration.parent) return undefined;
3189031891
return getTypeOfPropertyOfContextualType(parentType, getSymbolOfDeclaration(declaration).escapedName);
3189131892
}
3189231893

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//// [tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts] ////
2+
3+
=== classStaticPropertyNoSpuriousCircularityError1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/62552
5+
6+
function id<T>(x: T): T {
7+
>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0))
8+
>T : Symbol(T, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 12))
9+
>x : Symbol(x, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 15))
10+
>T : Symbol(T, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 12))
11+
>T : Symbol(T, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 12))
12+
13+
return x
14+
>x : Symbol(x, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 2, 15))
15+
}
16+
17+
const Foo = id(class {
18+
>Foo : Symbol(Foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 5))
19+
>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0))
20+
21+
static readonly foo = id(42) // ok
22+
>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 22))
23+
>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0))
24+
25+
})
26+
27+
Foo.foo // 42
28+
>Foo.foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 22))
29+
>Foo : Symbol(Foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 5))
30+
>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 6, 22))
31+
32+
const Foo2 = id(class {
33+
>Foo2 : Symbol(Foo2, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 5))
34+
>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0))
35+
36+
static foo = id(42) // ok
37+
>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 23))
38+
>id : Symbol(id, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 0, 0))
39+
40+
})
41+
42+
Foo2.foo // number
43+
>Foo2.foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 23))
44+
>Foo2 : Symbol(Foo2, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 5))
45+
>foo : Symbol((Anonymous class).foo, Decl(classStaticPropertyNoSpuriousCircularityError1.ts, 12, 23))
46+
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//// [tests/cases/compiler/classStaticPropertyNoSpuriousCircularityError1.ts] ////
2+
3+
=== classStaticPropertyNoSpuriousCircularityError1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/62552
5+
6+
function id<T>(x: T): T {
7+
>id : <T>(x: T) => T
8+
> : ^ ^^ ^^ ^^^^^
9+
>x : T
10+
> : ^
11+
12+
return x
13+
>x : T
14+
> : ^
15+
}
16+
17+
const Foo = id(class {
18+
>Foo : typeof (Anonymous class)
19+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
20+
>id(class { static readonly foo = id(42) // ok}) : typeof (Anonymous class)
21+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
22+
>id : <T>(x: T) => T
23+
> : ^ ^^ ^^ ^^^^^
24+
>class { static readonly foo = id(42) // ok} : typeof (Anonymous class)
25+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
26+
27+
static readonly foo = id(42) // ok
28+
>foo : 42
29+
> : ^^
30+
>id(42) : 42
31+
> : ^^
32+
>id : <T>(x: T) => T
33+
> : ^ ^^ ^^ ^^^^^
34+
>42 : 42
35+
> : ^^
36+
37+
})
38+
39+
Foo.foo // 42
40+
>Foo.foo : 42
41+
> : ^^
42+
>Foo : typeof (Anonymous class)
43+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
44+
>foo : 42
45+
> : ^^
46+
47+
const Foo2 = id(class {
48+
>Foo2 : typeof (Anonymous class)
49+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
50+
>id(class { static foo = id(42) // ok}) : typeof (Anonymous class)
51+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
52+
>id : <T>(x: T) => T
53+
> : ^ ^^ ^^ ^^^^^
54+
>class { static foo = id(42) // ok} : typeof (Anonymous class)
55+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
56+
57+
static foo = id(42) // ok
58+
>foo : number
59+
> : ^^^^^^
60+
>id(42) : 42
61+
> : ^^
62+
>id : <T>(x: T) => T
63+
> : ^ ^^ ^^ ^^^^^
64+
>42 : 42
65+
> : ^^
66+
67+
})
68+
69+
Foo2.foo // number
70+
>Foo2.foo : number
71+
> : ^^^^^^
72+
>Foo2 : typeof (Anonymous class)
73+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
74+
>foo : number
75+
> : ^^^^^^
76+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/62552
5+
6+
function id<T>(x: T): T {
7+
return x
8+
}
9+
10+
const Foo = id(class {
11+
static readonly foo = id(42) // ok
12+
})
13+
14+
Foo.foo // 42
15+
16+
const Foo2 = id(class {
17+
static foo = id(42) // ok
18+
})
19+
20+
Foo2.foo // number

0 commit comments

Comments
 (0)