Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tsc with allowJs reports TS9005 error for anonymous constructor functions #55172

Closed
dreusel opened this issue Jul 27, 2023 · 2 comments · Fixed by #55472
Closed

tsc with allowJs reports TS9005 error for anonymous constructor functions #55172

dreusel opened this issue Jul 27, 2023 · 2 comments · Fixed by #55472
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@dreusel
Copy link

dreusel commented Jul 27, 2023

Bug Report

Declaring a constructor function like so:

const SomeConstructor = function() {
	this.x = 1;
};

leads to typescript reporting error "TS9005": Declaration emit for this file requires using private name 'SomeConstructor'. An explicit type annotation may unblock declaration emit.
However the practically equivalent using a named function:

function SomeConstructor () {
	this.x = 1;
};

works fine.

It seems to me that the TS compiler should not care which of these notations is used. But even if the difference is intentional, the error message generated seems incorrect or unhelpful and misleading at least. Also the hint to add type annotations seems inappropriate; no amount of explicit type annotations will make this error go away.

Similar errors get generated when using the following constructs:

module.exports = {
	SomeConstructor: function () {
		this.x = 1;
	}
};

or

module.exports = function () {
	this.x = 1;
};

My tsconfig.json:

{
	"include": ["*.js"],
	"compilerOptions": {
		"allowJs": true,
		"declaration": true,
		"outDir": "dist",
		"skipLibCheck": true
	}
}

🔎 Search Terms

typescript TS9005
Declaration emit for this file requires using private name
typescript allowJs error 9005 const function class declaration
typescript allowJs error 9005 anonymous function class declaration

🕗 Version & Regression Information

This also happens in the Nightly version in the playground:
https://www.typescriptlang.org/play?strict=false&noImplicitAny=false&strictFunctionTypes=false&strictPropertyInitialization=false&strictBindCallApply=false&noImplicitThis=false&noImplicitReturns=false&alwaysStrict=false&ts=5.2.0-dev.20230727&filetype=js&strictNullChecks=false#code/MYewdgzgLgBAyiAtgUwMLmgJwK7CiTGAXhgDNsw8BLcGACgEoYBvAKAEgoALKiAOgAexGAEYA3KwC+EoA

It does not happen with versions 3.3.3-3.6.3:
https://www.typescriptlang.org/play?strict=false&noImplicitAny=false&strictFunctionTypes=false&strictPropertyInitialization=false&strictBindCallApply=false&noImplicitThis=false&noImplicitReturns=false&alwaysStrict=false&ts=3.6.3&filetype=js&strictNullChecks=false#code/MYewdgzgLgBAyiAtgUwMLmgJwK7CiTGAXhgDNsw8BLcGACgEoYBvAKAEgoALKiAOgAexGAEYA3KwC+EoA

However this versions also dont generate any typing information (.D.TS).

It seems to start happening with version 3.7.5:
https://www.typescriptlang.org/play?strict=false&noImplicitAny=false&strictFunctionTypes=false&strictPropertyInitialization=false&strictBindCallApply=false&noImplicitThis=false&noImplicitReturns=false&alwaysStrict=false&ts=3.7.5&filetype=js&strictNullChecks=false#code/MYewdgzgLgBAyiAtgUwMLmgJwK7CiTGAXhgDNsw8BLcGACgEoYBvAKAEgoALKiAOgAexGAEYA3KwC+EoA

  • This changed between versions 3.6.3 and 3.7.5
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

⏯ Playground Link

Playground link with relevant code

💻 Code

const SomeConstructor = function() {
	this.x = 1;
};

🙁 Actual behavior

tsc reports error "TS9005": Declaration emit for this file requires using private name 'SomeConstructor'. An explicit type annotation may unblock declaration emit.

This seems wrong because the equivalent code

function SomeConstructor () {
	this.x = 1;
};

works fine and it seems that there shouldn't be any relevant differences between these notations for the TS compiler.

🙂 Expected behavior

tsc should be happy

@weswigham
Copy link
Member

weswigham commented Aug 22, 2023

I spent too long looking at fixing this before realizing something critical - this isn't a regression, despite what the OP says. The playground doesn't report it, but in 3.6.3 and before, this code emits

error TS5053: Option 'allowJs' cannot be specified with option 'declaration'.

because we simply didn't have JS declaration emit at the time at all - it was added in 3.7. So we shouldn't worry about this from a regression perspective.

Now, from a usage perspective, I can understand wanting us to do better here, it's just a little odd. We need to do some pretty significant rewriting for symbols like this. This currently doesn't work because we try to emit const Name: typeof Thing except we can't name Thing because it's an unreachable anonymous function. In the past, we've said we'd prefer a case like this to be handled by explicit annotation, because the "clean" solution is a new syntax like #41587, but that's stalled a bit after we had questions about nominality of the syntax. Instead, what we'd need to do is recognize the assignment is an anonymous psuedo-class-static structure and emit something along the lines of declare class Name { constructor(); member: type }, which is not actually something we do elsewhere right now - assignments generally emit as assignments today. #55472 implements just that, and emits the assignment directly as a function/class/namespace merge instead.

@brian6932
Copy link

brian6932 commented Feb 24, 2024

This doesn't seem solved?
Experiencing a similar thing here https://tsplay.dev/NV57Gw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants