microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.01k stars 12.48k forks source link

function members of primitives/builtins are not read-only #59904

Open nielstron opened 2 months ago

nielstron commented 2 months ago

🔎 Search Terms

builtin number string member readonly

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.4&ssl=6&ssc=1&pln=1&pc=1#code/DYUwLgBAHhC8ECYDcAoKA6AbgQ2AVxAHkAzOCACgQEotcCTUVRIBPMgIgAsRhgB7dqhboAxp2wAnAIKR4wsZJmogA

💻 Code

let x = 2;
x.valueOf = (2).valueOf;

let y = "hello";
y.charAt = y.charAt;

🙁 Actual behavior

Code compiles just fine, even with --strict enabled. Executing JavaScript fails:

can't assign to property "valueOf" on 2: not an object 

🙂 Expected behavior

Should be rejected by tsc as read-only assignment.

Additional information about the issue

Seems similar in nature to https://github.com/microsoft/TypeScript/issues/49113 Notably, array.length is allowed (because its legal in JS) but string.length is not (because it is illegal in JS). Since assigning to builtin functions is also illegal, this should be flagged by tsc.

RyanCavanaugh commented 2 months ago

What runtime are you using? This is valid in default DOM contexts. If you're using a custom environment that freezes these prototypes, you'd need to customize your lib appropriately

Image

nielstron commented 2 months ago

This happens both with node v20.16 and in the linked playground on MacOS. But it also does not throw an error in the browser console (Firefox).

nielstron commented 2 months ago

I am not aware of having changed any lib or using any custom environments...

nmain commented 2 months ago

Setting a property on a primitive is legal (but silently ignored) in sloppy contexts, and throws an error with "use strict"; or any implied strict context such as a module.

RyanCavanaugh commented 2 months ago

Ah, right. The type system doesn't have any notion of "valid in strict mode" vs not (we can only differentiate when this would be the case syntactically). Given that it's pretty hard to make this mistake unless you're intentionally trying to, I don't think we'd undertake the fairly invasive effort to change it unless there was a more compelling demonstration of how this comes up in practice.

nielstron commented 2 months ago

Sounds fine to me. Do you happen to know if this behavior is documented anywhere? "frozen builtins" did not yield any results upon search

nielstron commented 4 weeks ago

looks like LLM spam - this is entirely unrelated to my issue