Skip to content

Commit b2d122d

Browse files
committed
Fix spurious circularity caused by removeOptionalityFromDeclaredType
1 parent 3307aa0 commit b2d122d

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

src/compiler/checker.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ const enum TypeSystemPropertyName {
12331233
ResolvedTypeArguments,
12341234
ResolvedBaseTypes,
12351235
WriteType,
1236+
IsParameterWithUndefinedInAnnotation,
12361237
}
12371238

12381239
/** @internal */
@@ -9982,6 +9983,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
99829983
return !!(target as InterfaceType).baseTypesResolved;
99839984
case TypeSystemPropertyName.WriteType:
99849985
return !!getSymbolLinks(target as Symbol).writeType;
9986+
case TypeSystemPropertyName.IsParameterWithUndefinedInAnnotation:
9987+
return getNodeLinks(target as VariableDeclaration).isParameterWithUndefinedInAnnotation !== undefined;
99859988
}
99869989
return Debug.assertNever(propertyName);
99879990
}
@@ -27294,20 +27297,29 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2729427297

2729527298
/** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
2729627299
function removeOptionalityFromDeclaredType(declaredType: Type, declaration: VariableLikeDeclaration): Type {
27297-
if (pushTypeResolution(declaration.symbol, TypeSystemPropertyName.DeclaredType)) {
27300+
const links = getNodeLinks(declaration);
27301+
27302+
if (links.isParameterWithUndefinedInAnnotation === undefined) {
27303+
if (!pushTypeResolution(declaration, TypeSystemPropertyName.IsParameterWithUndefinedInAnnotation)) {
27304+
reportCircularityError(declaration.symbol);
27305+
return declaredType;
27306+
}
27307+
2729827308
const annotationIncludesUndefined = strictNullChecks &&
2729927309
declaration.kind === SyntaxKind.Parameter &&
2730027310
declaration.initializer &&
2730127311
getTypeFacts(declaredType) & TypeFacts.IsUndefined &&
27302-
!(getTypeFacts(checkExpression(declaration.initializer)) & TypeFacts.IsUndefined);
27303-
popTypeResolution();
27312+
!(getTypeFacts(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFacts.IsUndefined);
2730427313

27305-
return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType;
27306-
}
27307-
else {
27308-
reportCircularityError(declaration.symbol);
27309-
return declaredType;
27314+
if (!popTypeResolution()) {
27315+
reportCircularityError(declaration.symbol);
27316+
return declaredType;
27317+
}
27318+
27319+
links.isParameterWithUndefinedInAnnotation = !!annotationIncludesUndefined;
2731027320
}
27321+
27322+
return links.isParameterWithUndefinedInAnnotation ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType;
2731127323
}
2731227324

2731327325
function isConstraintPosition(type: Type, node: Node) {

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5997,6 +5997,7 @@ export interface NodeLinks {
59975997
declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter.
59985998
serializedTypes?: Map<string, SerializedTypeEntry>; // Collection of types serialized at this location
59995999
decoratorSignature?: Signature; // Signature for decorator as if invoked by the runtime.
6000+
isParameterWithUndefinedInAnnotation?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined".
60006001
}
60016002

60026003
/** @internal */

tests/baselines/reference/tsserver/inconsistentErrorInEditor2/should-not-error.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ FsWatches::
188188
FsWatchesRecursive::
189189

190190
Info 16 [00:00:24.000] event:
191-
{"seq":0,"type":"event","event":"semanticDiag","body":{"file":"^/untitled/ts-nul-authority/Untitled-1","diagnostics":[{"start":{"line":1,"offset":13},"end":{"line":1,"offset":24},"text":"'Foo' is referenced directly or indirectly in its own type annotation.","code":2502,"category":"error"},{"start":{"line":2,"offset":11},"end":{"line":2,"offset":14},"text":"Type alias 'Foo' circularly references itself.","code":2456,"category":"error"}]}}
191+
{"seq":0,"type":"event","event":"semanticDiag","body":{"file":"^/untitled/ts-nul-authority/Untitled-1","diagnostics":[]}}
192192
Before running immediate callbacks and checking length (1)
193193

194194
PolledWatches::

0 commit comments

Comments
 (0)