Skip to content

No widening to any[] when parent of expando has type annotation#3986

Merged
ahejlsberg merged 2 commits into
mainfrom
fix-3976
May 19, 2026
Merged

No widening to any[] when parent of expando has type annotation#3986
ahejlsberg merged 2 commits into
mainfrom
fix-3976

Conversation

@ahejlsberg
Copy link
Copy Markdown
Member

With this PR we don't widen empty array literals to any[] in expando property assignments when the expando object has a type annotation. This mirrors the behavior in Strada. Part of me wants to just treat such expando property assignments the same as property assignments in object literals, meaning that we'd type the literals as never[] when noImplicitAny: true, but that would be a breaking change.

function f1() {}
f1.a = [];  // Implicit any error

const f2 = function() {};
f2.a = [];  // Implicit any error

const f3 = () => {};
f3.a = [];  // Implicit any error

const f4: { (): void, a: string[] } = () => {};
f4.a = [];

const f5: { (): void, a: string[] } = function() {};
f5.a = [];

Fixes #3976.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the checker’s expando-property typing so that assigning an empty array literal ([]) to an expando property does not widen to any[] when the expando object’s containing declaration has an explicit type annotation. This aligns tsgo behavior with Strada and fixes the regression reported in #3976.

Changes:

  • Updates expando assignment initializer typing to skip the “empty array => widen to any[] + implicit-any error” path when the expando parent is type-annotated.
  • Adds a compiler regression test covering callable objects with fields (typed vs untyped) and expected TS7008 diagnostics/baselines.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

File Description
internal/checker/checker.go Skips empty-array widening to any[] for expando assignment declarations when the expando parent is type-annotated.
testdata/tests/cases/compiler/expandoPropertyEmptyArrayWidening.ts New regression test reproducing #3976 and asserting correct behavior for typed vs untyped expandos.
testdata/baselines/reference/compiler/expandoPropertyEmptyArrayWidening.* New reference baselines (types/symbols/errors) validating the updated behavior.

Comment on lines +17999 to +18005
// Return true if the parent symbol of the given assignment declaration symbol has declaration with a type
// annotation. For example, returns true for the symbol associated with `f.a` below:
//
// const f: { (): void, a: string[] } = () => {};
// f.a = [];
func (c *Checker) hasParentWithTypeAnnotation(symbol *ast.Symbol) bool {
if symbol.Parent != nil && symbol.Parent.ValueDeclaration != nil && ast.IsFunctionExpressionOrArrowFunction(symbol.Parent.ValueDeclaration) {
@ahejlsberg ahejlsberg added this pull request to the merge queue May 19, 2026
Merged via the queue into main with commit 21b8d00 May 19, 2026
25 checks passed
@ahejlsberg ahejlsberg deleted the fix-3976 branch May 19, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tsgo does not correctly infer array type assignment on callable type with fields since 20260503.1

3 participants