-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Incorrect behavior of template strings when compiling to pre-ES6 targets #43686
Comments
Is this a duplicate of #27460? If you use modules (include an |
Hi Daniel, I do not believe this is a duplicate of #27460 or has anything to do with caching. As far as I could investigate, the issue here is that depending on the compilation target, different methods of an object will be called when interpolated in a template string due to incorrect polyfilling. I came across this issue in a module in my production code to begin with. π For some context, I'm currently using the The following is a complete module which triggered the issue. There is a bunch of unrelated code there, with the offending line at the bottom. import { CommandRequest } from "../request";
import { Permissions } from "discord.js";
import { CommandParameter, Command } from "../command";
import MentionConverter from "../type_converters/MentionConverter";
import StringConverter from "../type_converters/StringConverter";
export default <Command>{
parameters: [
new CommandParameter("target user id", MentionConverter),
new CommandParameter("role name", StringConverter),
new CommandParameter("role color", StringConverter),
],
permissions: [Permissions.FLAGS.MANAGE_ROLES],
async execute(
{ source }: CommandRequest,
target_user_id: string,
role_name: string,
role_color: string
): Promise<void> {
const target_member = source.guild?.members.cache.get(target_user_id);
if (!target_member) return;
const role_options = {
data: {
name: role_name,
color: role_color,
permissions: 0,
mentionable: true,
},
};
const role = await source.guild?.roles.create(role_options);
if (!role) return;
target_member.roles.add(role.id).then(() => {
source.channel.send(
// target_member interpolated as `<@!some_id>` in ES6, `some_id` in ES5
`Gave ${target_member} a new role \`${role.name}\``
);
});
},
}; |
Whoops, sorry, I misread the issue. |
It does seem to be the same as #39744 though. |
Ah, that would be it, yes. It didn't come up when I searched for prior reports before submitting, must've been a poor choice of keywords on my part. Sorry about that. Closing as duplicate. |
Bug Report
π Search Terms
template string literal interpolation
π Version & Regression Information
I tested this behavior locally on v4.2.4 and in the playground on Nightly.
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
When using template strings, if the compilation target does not natively support them (i.e. pre-ES6), the template string will be compiled into a series of concatenations using the
+
operator, which internally uses thevalueOf()
method to convert to a string.The ECMAScript standard for template strings specifies that
String.prototype.concat
usestoString()
internally, as can be seen in the playground code.If
valueOf()
andtoString()
methods return different values, the behavior will be different between different targets, leading to breakages and bugs.π Expected behavior
On targets that require polyfilling of template strings, compile them into a series of
concat()
operations to ensure consistent behavior across targets and compliance with the ECMAScript standard.The text was updated successfully, but these errors were encountered: