Request: support old ES "with" statement #41051
Comments
|
Despite this having never been supported in TS, I do believe this is actually the first issue requesting support for it. Trailblazing |
I actually am still wary of the spaghetti that TS developers will start cooking if it's supported, but these aren't lazy JavaScript developers, so that's somewhat reassuring. I think we just need more feedback from the community. |
|
The |
Refer to my note under the Checklist:
I stay within modularized code because it actually makes sense. Note that I am not suggesting that TS support the statement and just remove type annotations like normal, but instead transpile the statement entirely.
See how it transpiles variable accesses into object lookups, which should have the same result as if it had not used the Simply letting the |
|
By design TypeScript cannot alter the runtime behavior of the code so it’s out of the equation to emit something different from the entered JavaScript code except for downleveling. |
But this is a syntax level part of ECMAScript, just like async/await is, we could classify it as down leveling due to it not being supported by our output target (ES5+). (More like the opposite of down leveling, but you get the idea.) |
|
Downleveling would be type-directed emit, so if your request is that, it's out of scope |
|
Dang, guess this classifies as "out of scope" :( |
|
Update this can be done without type based code emit. input: const foo = {
bar: "baz",
qux: "foobar"
};
with ( foo ) {
console.log(bar, qux);
}output: const foo = {
bar: "baz",
qux: "foobar"
};
{
const __with_scope_0 = foo;
console.log(
"bar" in __with_scope_0 ? __with_scope_0.bar : bar,
"qux" in __with_scope_0 ? __with_scope_0.qux : qux
);
// (: bar) in the conditional operator accesses the outer scope's "bar"
}Example of nested with ( foo ) {
with ( bar ) {
console.log(a);
}
}output: {
const __with_scope_0 = foo;
{
const __with_scope_1 = bar;
console.log(
'a' in __with_scope_1 ? __with_scope_1.a : ('a' in __with_scope_0 ? __with_scope_0.a : a)
);
}
}It should always be possible to transpile like this, because JS identifiers are always representable as constant strings, and are always static in the scope. Even if the user brings arbitrary identifiers into scope via eval(), it would be found in the last section of the conditional operator. The number of with scopes is always static and able to be emit at compile-time, as they cannot be introduced dynamically (e.g. via function calls), and they aren't be able to leak variables outside of their scope. |
|
Furthermore, types can also be resolved as unions of everything that the conditional operations would return! |
|
I am the maintainer of the official Vue IDE plugin. Due to the particularity of the Vue template syntax, we need to use the |
I did not thoroughly search for this!
I'm sorry, it's pretty hard to search for such a common word, there were thousands of issues that use "with," but I tried looking through the first few hundred.
Suggestion
TypeScript support (a restricted subset of) the old JavaScript keyword: "with."
Use Cases
Simplifies code that accesses a large number of different, yet known keys of an object in quick succession.
Examples
output:
Checklist
My suggestion meets these guidelines:
~ This is a runtime feature, but this is already a feature that was implemented in ECMAScript itself (at some point).
Technically, it has not been removed. It is merely disallowed in strict mode.
I do not recommend supporting the actual ECMAScript "with" statement (I hate that the
self/window/globalThisobject is still global).Instead, I suggest that a very restricted subset is supported.
It would have to be very restrictive in order to not bring back the problems of the original "with."
Suggested restrictions to ensure code can still be typed and remain safe:
const(function calls can mutate non-const variables).(The variable restriction may be alleviated if the code is transpiled into a block with a variable assignment.)
It is very possible to transpile
withto perfectly safe runtime code that can be guaranteed to be as safe as if one had explicitly accessed the object.It wouldn't be hard if only supporting a subset, yet there are other implications to consider, such as performance, especially with nested
withstatements.(And yes, this could also be used to create the most hellish spaghetti code you have ever seen.)
The text was updated successfully, but these errors were encountered: