,
value: V,
state: { [name: string]: T }
) => R.assoc(prop, reducer(value, state[prop]), state)
);
```
#### TypeScript: keep parens around with yield/await non-null assertion ([#2149](https://github.com/prettier/prettier/pull/2149)) by [@azz](https://github.com/azz)
For better or worse, we decided to manually handle adding parenthesis. So when a new operator is introduced, we need to make sure that we add correct parenthesis when nested with any other combination of operators. In this case, we missed await inside of TypeScript `!`.
```ts
// Before
const bar = await foo(false)!;
// After
const bar = (await foo(false))!;
```
#### TypeScript: Print {} in import if it's in the source ([#2150](https://github.com/prettier/prettier/pull/2150)) by [@azz](https://github.com/azz)
We use typescript-eslint-parser project that translates TypeScript AST into estree AST in order for prettier to print it. From time to time we're going to find edge cases that it doesn't handle yet. In this case, it didn't give a way to tell that there's an empty `{}`, which apparently is important for TypeScript. Thankfully, the team is very responsive and they fixed it after we put a workaround inside of prettier.
```ts
// Before
import from "@types/googlemaps";
// After
import {} from "@types/googlemaps";
```
#### TypeScript: Always break interfaces onto multiple lines ([#2161](https://github.com/prettier/prettier/pull/2161)) by [@azz](https://github.com/azz)
The code that implements `interface` is shared with the code that prints `object`s, which contains a rule to keep them expanded if there's a `\n` inside. But, this is not the intended behavior for interfaces. We always want to expand, like we do for classes, even if it fits 80 columns.
```ts
// Before
interface FooBar { [id: string]: number; }
// After
interface FooBar {
[id: string]: number;
}
```
#### TypeScript: Fix extra semicolon in ambient typescript declaration emit ([#2167](https://github.com/prettier/prettier/pull/2167)) by [@azz](https://github.com/azz)
`no-semi` and `semi` are often requested but on the prettier team we're one step ahead and implemented `two-semi` for you! Just kidding, it was a bug and is now fixed ;)
```ts
// Before
declare module "classnames" {
export default function classnames(
...inputs: (string | number | false | object | undefined)[]
): string;;
}
// After
declare module "classnames" {
export default function classnames(
...inputs: (string | number | false | object | undefined)[]
): string;
}
```
#### TypeScript: group function params in call/construct signatures ([#2169](https://github.com/prettier/prettier/pull/2169)) by [@azz](https://github.com/azz)
Adding a comment before a method used to take into account the comment length and would often expand the method when it wasn't expected. Thankfully, it was a simple fix, just wrap the output in a `group`.
```ts
// Before
interface TimerConstructor {
// Line-splitting comment
new (
interval: number,
callback: (handler: Timer) => void
): Timer;
}
interface TimerConstructor {
// Line-splitting comment
new (interval: number, callback: (handler: Timer) => void): Timer;
}
```
#### TypeScript: Upgrade tsep ([#2183](https://github.com/prettier/prettier/pull/2183)) by [@azz](https://github.com/azz)
This bug was very annoying if you ran into it: anytime you formatted the code, it would add one more `_` to the object key!
```ts
// Before
obj = {
__: 42
___: 42
};
// After
obj = {
_: 42
__: 42
};
```
#### TypeScript: break on multiple interface extends ([#2085](https://github.com/prettier/prettier/pull/2085)) by [@azz](https://github.com/azz)
Unlike in JavaScript, TypeScript lets you extend multiple classes at once. It turns out that people use this feature and prettier now does a better job at printing it.
```ts
// Before
export interface ThirdVeryLongAndBoringInterfaceName extends AVeryLongAndBoringInterfaceName, AnotherVeryLongAndBoringInterfaceName, AThirdVeryLongAndBoringInterfaceName {}
// After
export interface ThirdVeryLongAndBoringInterfaceName
extends AVeryLongAndBoringInterfaceName,
AnotherVeryLongAndBoringInterfaceName,
AThirdVeryLongAndBoringInterfaceName {}
```
#### TypeScript: handle ObjectPattern instead of ObjectExpression inside BinaryExpression ([#2238](https://github.com/prettier/prettier/pull/2238)) by [@azz](https://github.com/azz)
This one isn't very interesting, it's an edge case that's not properly handled in the TypeScript -> estree conversion.
```ts
// Before
call(c => { bla: 1 }) || [];
// After
call(c => ({ bla: 1 })) || [];
```
#### Preserve lines after directives ([#2070](https://github.com/prettier/prettier/pull/2070))
By supporting TypeScript, prettier is now being used in a lot of Angular codebases which exercises edge cases that were not properly handled. In this case, we didn't preserve empty lines after directives inside of a function.
```ts
// Before
export default class {
constructor($log, $uibModal) {
"ngInject";
Object.assign(this, { $log, $uibModal });
// After
export default class {
constructor($log, $uibModal) {
"ngInject";
Object.assign(this, { $log, $uibModal });
```
### JavaScript
This release is very light in terms of JavaScript changes, which is awesome. We're starting to see the light at the end of the tunnel and get towards a great pretty printer. We're never going to get to a 100% perfect automatic pretty printer. The goal is that for every issue we get, there are no clear ways to improve the way it is printed without regressing other pieces.
#### Allow JSX lines to be recombined ([#1831](https://github.com/prettier/prettier/pull/1831)) by [@karl](https://github.com/karl)
The goal of prettier is to have a consistent way to format your code: given an AST, we always print the same way. In two places we had to compromise and read the original format: JSX and Objects. With this change, we're no longer relying on the original input for JSX with text inside. This lets us reflow text inside of JSX.
```jsx
// Before
const Abc = () => {
return (
Please state your
{" "}
name
{" "}
and
{" "}
occupation
{" "}
for the board of directors.
);
};
// After
const Abc = () => {
return (
Please state your name and occupation for the board of
directors.
);
}
```
#### Break on non-literal computed member expression ([#2087](https://github.com/prettier/prettier/pull/2087)) by [@azz](https://github.com/azz)
Printing member chains is the most complicated piece of prettier and we keep finding small tweaks we can do to make it a better experience.
```js
// Before
nock(/test/)
.matchHeader("Accept", "application/json")[httpMethodNock(method)]("/foo")
.reply(200, {
foo: "bar",
});
// After
nock(/test/)
.matchHeader("Accept", "application/json")
[httpMethodNock(method)]("/foo")
.reply(200, {
foo: "bar",
});
```
#### Indent first variable in one-var scenario ([#2095](https://github.com/prettier/prettier/pull/2095)) by [@azz](https://github.com/azz)
Up until recently we haven't done much to support printing multiple variables in a single declaration as the most common practice is to do one variable declaration per variable. For single declarations, we don't want to indent it, but it turns out that we do when there are other ones afterwards, otherwise it looks weird.
```js
// Before
var templateTagsMapping = {
'%{itemIndex}': 'index',
'%{itemContentMetaTextViews}': 'views'
},
separator = '•';
// After
var templateTagsMapping = {
'%{itemIndex}': 'index',
'%{itemContentMetaTextViews}': 'views'
},
separator = '•';
```
#### Allow break with both default named import ([#2096](https://github.com/prettier/prettier/pull/2096)) by [@azz](https://github.com/azz)
This one is an unfortunate regression from 1.4 where we inlined import that only contained a single element. Turns out the definition of a single element allowed a single type and a single element. This is now corrected!
```js
// Before
import transformRouterContext, { type TransformedContextRouter } from '../../helpers/transformRouterContext';
// After
import transformRouterContext, {
type TransformedContextRouter
} from '../../helpers/transformRouterContext';
```
#### Turn allowImportExportEverywhere on ([#2207](https://github.com/prettier/prettier/pull/2207)) by [@zimme](https://github.com/zimme)
The goal of prettier is to format code people write in practice, so we enable loose/experimental modes for all the parsers we support. Babylon allows you to write import within a function, which is not part of the standard, but it doesn't cost us much to allow it.
```js
// Before
ParseError
// After
function f() {
import x from 'x';
}
```
#### Support inline template for new calls ([#2222](https://github.com/prettier/prettier/pull/2222))
We keep adding features for function calls and have to backport them to new calls as they have a different AST node type but in practice we want to treat them the same. This fix refactored the two so that they are going through the same call site, so hopefully should prevent more from sneaking in.
```js
// Before
new Error(
formatErrorMessage`
This is a really bad error.
Which has more than one line.
`
);
// After
new Error(formatErrorMessage`
This is a really bad error.
Which has more than one line.
`);
```
#### Don't indent + in object value ([#2227](https://github.com/prettier/prettier/pull/2227))
When we switched to using the same heuristic for assignment (`a = b`) for objects (`{a: b}`), we forgot to fix the indentation. Now it's fixed.
```js
// Before
var abc = {
thing:
"asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" +
"asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" +
"asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf",
}
// After
var abc = {
thing:
"asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" +
"asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" +
"asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf",
}
```
#### Handle conditions inside of a ternary ([#2228](https://github.com/prettier/prettier/pull/2228))
Prettier already had a special case when the expression was a conditional but it didn't apply when the conditional was the left part of a ternary. Now it does.
```js
// Before
room = room.map((row, rowIndex) =>
row.map(
(col, colIndex) =>
rowIndex === 0 ||
colIndex === 0 ||
rowIndex === height ||
colIndex === width
? 1
: 0
)
);
// After
room = room.map((row, rowIndex) =>
row.map(
(col, colIndex) =>
rowIndex === 0 ||
colIndex === 0 ||
rowIndex === height ||
colIndex === width
? 1
: 0
)
);
```
#### Add caching for printing ([#2259](https://github.com/prettier/prettier/pull/2259))
With the 1.0 release, we fixed a bug in the printing that introduced an exponential behavior. We've been able to mitigate the biggest issue such that reasonable code didn't time out, but it wasn't completely fixed it. By adding a caching layer at the right spot, we should now be in the clear.
This should make printing the IR of prettier using prettier in debug mode no longer time out.
```js
// Before
...times out...
// After
someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
return someObject.someFunction().then(function () {
anotherFunction();
});
});
});
});
});
});
});
});
});
```
#### Fix variance location ([#2261](https://github.com/prettier/prettier/pull/2261))
We refactored the code that prints modifiers when we introduced TypeScript support and accidentally moved around the variance (`+`) part before `static` which is not valid in Flow. This is now fixed.
```ts
// Before
class Route {
+static param: T;
}
// After
class Route {
static +param: T;
}
```
### Miscellaneous
#### Various fixes for range and cursor tracking ([#2266](https://github.com/prettier/prettier/pull/2266), [#2248](https://github.com/prettier/prettier/pull/2248), [#2250](https://github.com/prettier/prettier/pull/2250), [#2136](https://github.com/prettier/prettier/pull/2136)) by [@CiGit](https://github.com/CiGit) and [@josephfrazier](https://github.com/josephfrazier)
Both those features were introduced in the last release and we discovered a bunch of issues when actually using them in production. A bunch of them got fixed, if you see more, please report them!