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

.length property of function literals is not readonly #49113

Open
STRd6 opened this issue May 14, 2022 · 1 comment · May be fixed by #49146
Open

.length property of function literals is not readonly #49113

STRd6 opened this issue May 14, 2022 · 1 comment · May be fixed by #49146
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@STRd6
Copy link

STRd6 commented May 14, 2022

Bug Report

Function .length property is inconsistently readonly depending on whether Function constructor is used or not.

🔎 Search Terms

function length readonly

🕗 Version & Regression Information

v4.6.2 (haven't checked older versions)

⏯ Playground Link

Playground link with relevant code

💻 Code

const f = new Function()
f.length = 1 // Error here: Cannot assign to 'length' because it is a read-only property.

const f2 = () => {}
f2.length = 1 // No error here

🙁 Actual behavior

The length property of the function created with new Function() is readonly while the length property of function literals is not.

🙂 Expected behavior

Both length properties should be readonly. Alternative both could be non-readonly but that seems worse since JS doesn't modify the length when assigning a value.

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels May 16, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone May 16, 2022
@Andarist
Copy link
Contributor

This is an interesting case 😅 The length property becomes part of the created namespace/symbol for the function declaration in the binder, in its bindSpecialPropertyAssignment, it reaches this line:

bindStaticPropertyAssignment(cast(node.left, isBindableStaticNameExpression));

And later on, the checker doesn't error on a readonly prop here:
https://github.dev/microsoft/TypeScript/blob/95731f03979985609c9fd662f179be5b9cea3470/src/compiler/checker.ts#L29063-L29066
because the symbol for this prop comes from the created namespace~ in the binder and not from the global interface Function that declares length to be readonly. In a sense, the created namespace property "shadows" over the correct one.

So my first thought was to... avoid binding this. However, the binder doesn't have access to any type information so I can't check if the property already exists there and if it's a readonly. I could special case the length there, in the implementation, but that seems dirty and maybe there is a better way?

Alternatively, this could be handled in the checker, but then the symbol for this special property would still exist on this namespace~ and this feels error-prone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants