dmnd / dedent

⬅️ ES6 string tag that strips indentation from multi-line strings.
MIT License
917 stars 35 forks source link

escaped `$` and `{` characters are not handled correctly #45

Closed G-Rath closed 1 year ago

G-Rath commented 1 year ago

Follow on from #2 - currently dedent does not treat $ or { as special when determining what it should do with escaped characters:

dedent`\$` === '\\$'
dedent`\{` === '\\{'
JoshuaKGoldberg commented 1 year ago

🤔 maybe this is me not understanding template literal strings well, but I don't follow why that should be the case. The dedent function isn't doing anything special with escaping special characters such as $ and {. Can you help me explain why the behavior should be changed?

G-Rath commented 1 year ago

Because otherwise you can't dedent strings with ${ i.e. https://github.com/jest-community/eslint-plugin-jest/blob/02ec945f0794949ce38a11addb0ef3ceafa1aed2/src/rules/__tests__/no-identical-title.test.ts#L108-L113

    dedent`
      describe("foo", () => {
        it(\`ignores $\{someVar} with the same title\`, () => {});
        it(\`ignores $\{someVar} with the same title\`, () => {});
      });
    `.replace(/\\\{/u, '{'),

The replace is the workaround for this - note that I don't have to do it for backticks because that was already addressed in #2.

Technically the best form would be detecting that it's ${, but I think it's reasonable to say that special template string characters should be handled like this because you can otherwise just add a second \ i.e. say I was testing a JS parser and that it didn't pick up escaped interpolation:

    dedent`
      describe("foo", () => {
        it(\`ignores $\\{someVar} with the same title\`, () => {});
        it(\`ignores $\\{someVar} with the same title\`, () => {});
      });
    `
meowtec commented 1 year ago

My workaround be like:

dedent`
  export function Demo({ active }) {
    return (
      <div
        className={\`demo $${''}{active ? 'active' : ''}\`}
      ></div>
    )
  }
`

It is ugly