---
authors: "duailibe"
title: "Prettier 1.18: Lots of fixes and OpenCollective"
---

This release doesn't include shiny new features, but has lots of fixes for JavaScript, specially JSX and template literals, TypeScript and Markdown.

It's also a good opportunity to remind that Prettier is now accepting donations! If you enjoy Prettier and would like to support our work, head to our [OpenCollective](https://opencollective.com/prettier).

<!-- truncate -->

## Highlights

### JavaScript

#### Stop breaking simple template literals ([#5979] by [@jwbay])

This is one of the Prettier parts that get a lot of change requests: breaking simple expressions inside template literals. Previously Prettier would break the expressions in multiple lines if the whole literal exceeded the print width. Now, we'll prevent breaking if the expression is simple.

This is an improvement to what we had before, but there's still work to be done in this area.

<!-- prettier-ignore -->
```js
// Input
console.log(chalk.white(`Covered Lines below threshold: ${coverageSettings.lines}%. Actual: ${coverageSummary.total.lines.pct}%`))

// Output (Prettier stable)
console.log(
  chalk.white(
    `Covered Lines below threshold: ${coverageSettings.lines}%. Actual: ${
      coverageSummary.total.lines.pct
    }%`
  )
);

// Output (Prettier master)
console.log(
  chalk.white(
    `Covered Lines below threshold: ${coverageSettings.lines}%. Actual: ${coverageSummary.total.lines.pct}%`
  )
);
```

#### Stop converting empty JSX elements to self-closing elements ([#6127] by [@duailibe])

Prettier has always converted empty JSX elements (`<div></div>`) to self-closing elements (`<div />`) because those are equivalent.

We have received feedback that during development, one would like to type the opening and closing tags and leave them to add the children later, but Prettier would convert it to a self-closing element, forcing the developer to manually convert them back. This has changed in this release.

<!-- prettier-ignore -->
```js
// Input
function Foo() {
  return <div></div>;
}

// Output (Prettier stable)
function Foo() {
  return <div />;
}

// Output (Prettier master)
function Foo() {
  return <div></div>;
}
```

## Other changes

### JavaScript

#### Fix closure compiler typecasts ([#5947] by [@jridgewell])

If a closing parenthesis follows after a typecast in an inner expression, the typecast would wrap everything to that following parenthesis.

<!-- prettier-ignore -->
```js
// Input
test(/** @type {!Array} */(arrOrString).length);
test(/** @type {!Array} */((arrOrString)).length + 1);
// Output (Prettier stable)
test(/** @type {!Array} */ (arrOrString.length));
test(/** @type {!Array} */ (arrOrString.length + 1));
// Output (Prettier master)
test(/** @type {!Array} */ (arrOrString).length);
test(/** @type {!Array} */ (arrOrString).length + 1);
```

#### Fix closure typecasts without spaces ([#6116] by [@jridgewell])

Previously, a space was required between the `@type` and opening `{` of a closure typecast, or else the enclosing parenthesis would be removed. Closure itself does not require a space.

<!-- prettier-ignore -->
```tsx
// Input
const v = /** @type{string} */(value);

// Output (Prettier stable)
const v = /** @type{string} */ value;

// Output (prettier master)
const v = /** @type{string} */ (value);
```

#### Prevent adding quotes when using `--quote-props=consistent` and objects had numbers or computed expressions as keys ([#6119] and [#6138] by [@duailibe])

Previously, Prettier added unnecessary quotes to keys of an object, or properties and methods of classes, if there was at least one computed key with a "complex" expression (e.g. a member expression) or a numeric literal.

<!-- prettier-ignore -->
```js
// Input
const obj = {
  foo: "",
  [foo.bar]: "",
};

const other = {
  foo: "",
  1: ""
};

// Output (Prettier stable)
const obj = {
  "foo": "",
  [foo.bar]: "",
};

const other = {
  "foo": "",
  1: ""
};

// Output (Prettier master)
const obj = {
  foo: "",
  [foo.bar]: "",
};

const other = {
  foo: "",
  1: ""
};
```

#### Add parenthesis in JSX spread element with logical expressions ([#6130] by [@duailibe])

Previously, Prettier didn't add parenthesis in JSX spread elements because they aren't necessary, but for the sake of consistency with spread operator in objects and arrays, we'll add to JSX as well.

<!-- prettier-ignore -->
```js
// Input
<Component {...(props || {})} />;

// Output (Prettier stable)
<Component {...props || {}} />;

// Output (Prettier master)
<Component {...(props || {})} />;
```

#### Correctly handle comments in empty arrow function expressions ([#6086] by [@evilebottnawi])

<!-- prettier-ignore -->
```js
// Input
const fn = (/*event, data*/) => doSomething(anything);

// Output (Prettier stable)
const fn = () => /*event, data*/ doSomething(anything);

// Output (Prettier master)
const fn = (/*event, data*/) => doSomething(anything);
```

#### Do not hug sequence expression in object properties ([#6088] by [@evilebottnawi])

<!-- prettier-ignore -->
```js
// Input
const a = {
  someKey:
    (longLongLongLongLongLongLongLongLongLongLongLongLongLongName, shortName)
};

// Output (Prettier stable)
const a = {
  someKey: (longLongLongLongLongLongLongLongLongLongLongLongLongLongName,
  shortName)
};

// Output (Prettier master)
const a = {
  someKey:
    (longLongLongLongLongLongLongLongLongLongLongLongLongLongName, shortName)
};
```

#### Add support for styled-jsx external styles ([#6089] by [@hongrich])

Add support for 2 external styles tags in `styled-jsx/css`: `css.global`, and `css.resolve`. https://github.com/zeit/styled-jsx/#external-css-and-styles-outside-of-the-component

The `css` template tag is already supported by Prettier.

<!-- prettier-ignore -->
```js
// Input
const styles = css.resolve`
.box {background:black;
}`;

// Output (Prettier stable)
const styles = css.resolve`
.box {background:black;
}`;

// Output (prettier master)
const styles = css.resolve`
  .box {
    background: black;
  }
`;
```

#### Keep parenthesis around functions and classes in `export default` declarations ([#6133] by [@duailibe])

Prettier was removing parenthesis from some expressions in `export default`, but if those are complex expressions that start with `function` or `class`, the parenthesis are required.

See below some practical examples, including one affecting TypeScript.

<!-- prettier-ignore -->
```ts
// Input
export default (function log() {}).toString();
export default (function log() {} as typeof console.log);

// Output (Prettier stable)
export default function log() {}.toString();
export default function log() {} as typeof console.log; // syntax error

// Output (Prettier master)
export default (function log() {}).toString();
export default (function log() {} as typeof console.log);
```

#### Address parentheses bugs for edge cases with call and `new` ([#6148] by [@bakkot])

Adding all and only the necessary parentheses when mixing `new` with function calls is tricky. This change fixes two issues where necessary parentheses were omitted and one when redundant parentheses were added.

<!-- prettier-ignore -->
```ts
// Input
new (x()``.y)();
new (x()!.y)();
new e[f().x].y()

// Output (Prettier stable)
new x()``.y();
new x()!.y();
new e[(f()).x].y();

// Output (Prettier master)
new (x())``.y();
new (x())!.y();
new e[f().x].y();
```

#### Fix nested embeds (JS in HTML in JS) ([#6038] by [@thorn0])

Previously, if JS code embedded in HTML (via `<script>`) embedded in JS (via a template literal) contained template literals, the inner JS was not formatted.

<!-- prettier-ignore -->
```js
// Input
const html = /* HTML */ `<script>var a=\`\`</script>`;

// Output (Prettier stable)
// SyntaxError: Expecting Unicode escape sequence \uXXXX (1:8)

// Output (Prettier master)
const html = /* HTML */ `
  <script>
    var a = \`\`;
  </script>
`;
```

#### Keep necessary parentheses around bind expressions passed to `new` expressions ([#6152] by [@sosukesuzuki])

Previously, Prettier removed necessary parentheses around a bind expression if it was passed to a `new` expression.

<!-- prettier-ignore -->
```js
// Input
new (a::b)();

// Output (Prettier stable)
new a::b();

// Output (Prettier master)
new (a::b)();
```

#### Prevent adding unnecessary parentheses around bind expressions in member expressions' properties ([#6159] by [@duailibe])

<!-- prettier-ignore -->
```js
// Input
f[a::b];

// Output (Prettier stable)
f[(a::b)];

// Output (Prettier master);
f[a::b];
```

### TypeScript

#### Keep trailing comma in TSX type parameters ([#6115] by [@sosukesuzuki])

Previously, a trailing comma after single type parameter in arrow function was cleaned up. The formatted result is valid as TS, but is invalid as TSX. This is now fixed in 1.19.

<!-- prettier-ignore -->
```tsx
// Input
type G<T> = any;
const myFunc = <T,>(arg1: G<T>) => false;

// Output (Prettier stable)
type G<T> = any;
const myFunc = <T>(arg1: G<T>) => false;

// Output (prettier master)
type G<T> = any;
const myFunc = <T,>(arg1: G<T>) => false;
```

#### Don’t breakup call expressions when the last argument is an arrow function with a simple return type ([#6106] by [@brainkim])

Fixes [an edge case][#6099] where we were splitting up call expressions containing arrow functions with simple return types.

<!-- prettier-ignore -->
```js
app.get("/", (req, res): void => {
  res.send("Hello World!");
});

// Output (Prettier stable)
app.get(
  "/",
  (req, res): void => {
    res.send("Hello World!");
  },
);

// Output (Prettier master)
app.get("/", (req, res): void => {
  res.send("Hello World!");
});
```

#### Keep a pair of parentheses when there are extra pairs ([#6131] by [@sosukesuzuki])

Previously, Prettier removed necessary parentheses when trying to remove unnecessary parentheses, in TypeScript.

<!-- prettier-ignore -->
```ts
// Input
type G = ((keyof T))[];

// Output (Prettier stable)
type G = keyof T[];

// Output (prettier master)
type G = (keyof T)[];
```

#### Keep necessary parentheses around non-null assertions ([#6136] by [@sosukesuzuki], [#6140] by [@thorn0], [#6148] by [@bakkot])

Previously, Prettier removed necessary parentheses around non-null assertions if the result of the assertion expression was called as a constructor.

<!-- prettier-ignore -->
```ts
// Input
const b = new (c()!)();

// Output (Prettier stable)
const b = new c()!();

// Output (Prettier master)
const b = new (c())!();
```

#### Keep line breaks within mapped types ([#6146] by [@sosukesuzuki])

Previously, Prettier removed line breaks within mapped types. To make it similar to how we treat object literals, we will keep the line breaks if they existed in the source.

<!-- prettier-ignore -->
```ts
// Input
type A<T> = {
  readonly [P in keyof T]: T[P];
};

// Output (Prettier stable)
type A<T> = { readonly [P in keyof T]: T[P] };

// Output (Prettier master)
type A<T> = {
  readonly [P in keyof T]: T[P];
};
```

#### Add trailing comma on tuple types with `--trailing-comma=all` ([#6172] by [@sosukesuzuki])

TypeScript supports a trailing comma on tuple types since version 3.3.

<!-- prettier-ignore -->
```ts
// Input
export type Foo = [
  number,
  number, // comment
];

// Output (Prettier stable)
export type Foo = [
  number,
  number // comment
];

// Output (Prettier master);
export type Foo = [
  number,
  number, // comment
];
```

### Markdown

#### Determine correctly the count of backticks in inline code ([#6110] by [@belochub])

By the CommonMark spec, it is required to 'choose a string of `n` backtick characters as delimiters, where the code does not contain any strings of exactly `n` backtick characters.'

This changes the method of finding the required count of backticks from using 2 backticks, when there is a backtick string of length 1 inside the inline code block, and using 1 backtick in all other cases, to finding a minimum length backtick string that can correctly be used as a delimiter.

<!-- prettier-ignore -->
````md
<!-- Input -->
``` 3 ``22`` `1` ```

`` 2 ```123``` `1` ``

<!-- Output (Prettier stable) -->
` 3 ``22`` `1` `

` 2 ```123``` `1` `

<!-- Output (Prettier master) -->
``` 3 ``22`` `1` ```

`` 2 ```123``` `1` ``
````

### Handlebars

While the Handlebars support is still in beta, [@GavinJoyce] is putting out some fixes so we can finally get to a stable release!

#### Avoid adding unwanted whitespace after components ([#6178] by [@GavinJoyce])

Previously, Prettier added a space before `/>` and a line break after, even when at the start of a line. Now, that extra space and line break is no longer present.

<!-- prettier-ignore -->
```hbs
// Input
<div>
  <UserGreeting
    @aVeryLongArgumentNameThatIsStillGoing={{@alsoAVeryLongArgument}}
  />
</div>

// Output (Prettier stable)
<div>
  <UserGreeting
    @aVeryLongArgumentNameThatIsStillGoing={{@alsoAVeryLongArgument}}
   />

</div>

// Output (Prettier master)
<div>
  <UserGreeting
    @aVeryLongArgumentNameThatIsStillGoing={{@alsoAVeryLongArgument}}
  />
</div>
```

### API

#### Prettier now works in Atom again ([#6129] by [@duailibe])

Atom has a security feature where code containing `eval` is not allowed to be run. One of Prettier's dependencies uses `eval` to prevent bundlers from including debug code. We've now made sure that this `eval` does not end up in the code we ship to npm, making Prettier play nice with Atom again.

[#5947]: https://github.com/prettier/prettier/pull/5947
[#5979]: https://github.com/prettier/prettier/pull/5979
[#6038]: https://github.com/prettier/prettier/pull/6038
[#6086]: https://github.com/prettier/prettier/pull/6086
[#6088]: https://github.com/prettier/prettier/pull/6088
[#6089]: https://github.com/prettier/prettier/pull/6089
[#6099]: https://github.com/prettier/prettier/pull/6099
[#6106]: https://github.com/prettier/prettier/pull/6106
[#6110]: https://github.com/prettier/prettier/pull/6110
[#6115]: https://github.com/prettier/prettier/pull/6115
[#6116]: https://github.com/prettier/prettier/pull/6116
[#6119]: https://github.com/prettier/prettier/pull/6119
[#6127]: https://github.com/prettier/prettier/pull/6127
[#6129]: https://github.com/prettier/prettier/pull/6129
[#6130]: https://github.com/prettier/prettier/pull/6130
[#6131]: https://github.com/prettier/prettier/pull/6131
[#6133]: https://github.com/prettier/prettier/pull/6133
[#6136]: https://github.com/prettier/prettier/pull/6136
[#6138]: https://github.com/prettier/prettier/pull/6138
[#6140]: https://github.com/prettier/prettier/pull/6140
[#6146]: https://github.com/prettier/prettier/pull/6146
[#6148]: https://github.com/prettier/prettier/pull/6148
[#6152]: https://github.com/prettier/prettier/pull/6152
[#6159]: https://github.com/prettier/prettier/pull/6159
[#6172]: https://github.com/prettier/prettier/pull/6172
[#6178]: https://github.com/prettier/prettier/pull/6178
[@belochub]: https://github.com/belochub
[@brainkim]: https://github.com/brainkim
[@duailibe]: https://github.com/duailibe
[@evilebottnawi]: https://github.com/evilebottnawi
[@hongrich]: https://github.com/hongrich
[@jridgewell]: https://github.com/jridgewell
[@jwbay]: https://github.com/jwbay
[@sosukesuzuki]: https://github.com/sosukesuzuki
[@thorn0]: https://github.com/thorn0
[@bakkot]: https://github.com/bakkot
[@gavinjoyce]: https://github.com/GavinJoyce
