---
authors: "sosukesuzuki"
title: "Prettier 2.7: new --cache CLI option and TypeScript 4.7 syntax!"
---

This release includes a new `--cache` CLI option. Enabling this option will use some attributes as cache keys and format files only if they have changed. This could dramatically improve CLI performance.

We've also added support formatting for TypeScript 4.7 syntax!

If you enjoy Prettier and would like to support our work, consider sponsoring us directly via [our OpenCollective](https://opencollective.com/prettier) or by sponsoring the projects we depend on, including [typescript-eslint](https://opencollective.com/typescript-eslint), [remark](https://opencollective.com/unified), and [Babel](https://opencollective.com/babel).

<!-- truncate -->

## Highlights

### TypeScript

#### Support TypeScript 4.7 ([#12896](https://github.com/prettier/prettier/pull/12896), [#12897](https://github.com/prettier/prettier/pull/12897), [#12898](https://github.com/prettier/prettier/pull/12898), [#12900](https://github.com/prettier/prettier/pull/12900), [#12921](https://github.com/prettier/prettier/pull/12921), [#12924](https://github.com/prettier/prettier/pull/12924), [#12959](https://github.com/prettier/prettier/pull/12959) by [@sosukesuzuki](https://github.com/sosukesuzuki))

Support [TypeScript 4.7](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7) new features!

##### [Instantiation Expressions](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#instantiation-expressions)

<!-- prettier-ignore -->
```ts
interface Box<T> {
  value: T;
}
function makeBox<T>(value: T) {
  return { value };
}
const makeHammerBox = makeBox<Hammer>;
const makeWrenchBox = makeBox<Wrench>;
```

##### [Optional Variance Annotations](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#optional-variance-annotations-for-type-parameters)

<!-- prettier-ignore -->
```ts
interface Animal {
  animalStuff: any;
}
interface Dog extends Animal {
  dogStuff: any;
}
type Getter<out T> = () => T;
type Setter<in T> = (value: T) => void;
```

##### [`extends` constraints for `infer`](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables)

<!-- prettier-ignore -->
```ts
type FirstString<T> = T extends [infer S extends string, ...unknown[]]
  ? S
  : never;
```

### CLI

#### Add `--cache` and `--cache-strategy` CLI options ([#12800](https://github.com/prettier/prettier/pull/12800) by [@sosukesuzuki](https://github.com/sosukesuzuki))

Two new CLI options have been added for a caching system similar to [ESLint's one](https://eslint.org/docs/user-guide/command-line-interface#caching).

Please see [the doc](https://prettier.io/docs/cli#--cache) for more details.

##### `--cache`

If this option is enabled, the following values are used as cache keys and the file is formatted only if one of them is changed.

- Prettier version
- Options
- Node.js version
- (if `--cache-strategy` is `content`) content of the file
- (if `--cache-strategy` is `metadata`) file metadata, such as timestamps

```bash
prettier --write --cache src
```

##### `--cache-strategy`

Strategy for the cache to use for detecting changed files. Can be either `metadata` or `content`. If no strategy is specified, `content` will be used.

```bash
prettier --write --cache --cache-strategy metadata src
```

## Other Changes

### JavaScript

#### Preserve blank line between export specifiers ([#12746](https://github.com/prettier/prettier/pull/12746) by [@sosukesuzuki](https://github.com/sosukesuzuki))

<!-- prettier-ignore -->
```jsx
// Input
export {
  // a
  foo1,

  // b
  bar1,
  baz1,
} from "mod";

// Prettier 2.6
export {
  // a
  foo1,
  // b
  bar1,
  baz1,
} from "mod";

// Prettier 2.7
export {
  // a
  foo1,

  // b
  bar1,
  baz1,
} from "mod";
```

#### Make more callee patterns recognized as "test call callee". ([#12779](https://github.com/prettier/prettier/pull/12779) by [@HosokawaR](https://github.com/HosokawaR))

Supports test calls like [Playwright `test.describe`](https://playwright.dev/docs/api/class-test#test-describe).

<!-- prettier-ignore -->
```jsx
// Input
test.step("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.only("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.parallel("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.parallel.only("does something really long and complicated so I have to write a very long name for the testThis is a very", () => {});

test.describe.serial("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.serial.only("does something really long and complicated so I have to write a very long name for the test", () => {});

// Prettier 2.6
test.step(
  "does something really long and complicated so I have to write a very long name for the test",
  () => {}
);

test.describe(
  "does something really long and complicated so I have to write a very long name for the test",
  () => {}
);

test.describe.only(
  "does something really long and complicated so I have to write a very long name for the test",
  () => {}
);

test.describe.parallel(
  "does something really long and complicated so I have to write a very long name for the test",
  () => {}
);

test.describe.parallel.only(
  "does something really long and complicated so I have to write a very long name for the testThis is a very",
  () => {}
);

test.describe.serial(
  "does something really long and complicated so I have to write a very long name for the test",
  () => {}
);

test.describe.serial.only(
  "does something really long and complicated so I have to write a very long name for the test",
  () => {}
);

// Prettier 2.7
test.step("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe
  .only("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe
  .parallel("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.parallel
  .only("does something really long and complicated so I have to write a very long name for the testThis is a very", () => {});

test.describe
  .serial("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.serial
  .only("does something really long and complicated so I have to write a very long name for the test", () => {});
```

#### Fix comment formats in ([#12860](https://github.com/prettier/prettier/pull/12860) by [@HosokawaR](https://github.com/HosokawaR))

This change fixes the comment format in `exports` to align with the comment format in `import`.

Although this change does not affect the comments format in `import`, follows change log contains examples of comments in `import` for reference.

<!-- prettier-ignore -->
```jsx
// Input
export {
  foo,

  bar as  // comment
		 baz,
}

import {
  foo,

  bar as  // comment
		 baz,
} from 'foo'

// Prettier 2.6
export {
  foo,
  bar as baz, // comment
};

import {
  foo,
  // comment
  bar as baz,
} from "foo";

// Prettier 2.7
export {
  foo,
  // comment
  bar as baz,
};

import {
  foo,
  // comment
  bar as baz,
} from "foo";

```

### TypeScript

#### Print `as` instead of `:` for `babel-ts` parser ([#12706](https://github.com/prettier/prettier/pull/12706) by [@HosokawaR](https://github.com/HosokawaR))

<!-- prettier-ignore -->
```tsx
// Input
[x as any] = x;

// Prettier 2.6
[x: any] = x;

// Prettier 2.7
[x as any] = x;
```

#### Fix formatting for typescript Enum with computed members ([#12930](https://github.com/prettier/prettier/pull/12930) by [@HosokawaR](https://github.com/HosokawaR))

<!-- prettier-ignore -->
```tsx
// Input
enum A {
  [i++],
}

// Prettier 2.6
enum A {
  i++,
}

// Prettier 2.7
enum A {
  [i++],
}
```

#### Stop parsing invalid code ([#12982](https://github.com/prettier/prettier/pull/12982) by [@fisker](https://github.com/fisker))

<!-- prettier-ignore -->
```tsx
// Input
const object = ({ methodName() });

// Prettier 2.6
const object = { methodName(); };

// Prettier 2.7
SyntaxError: Unexpected token. (1:29)
> 1 | const object = ({ methodName() });
    |                             ^^
```

### HTML

#### Support Speculation Rules API formatting in HTML ([#12882](https://github.com/prettier/prettier/pull/12882) by [@sosukesuzuki](https://github.com/sosukesuzuki))

Please read https://web.dev/speculative-prerendering/ for more information about the Speculation Rules API.

<!-- prettier-ignore -->
```html
<!-- Input -->
<script type="speculationrules">
  {
   "prerender": [
  {"source": "list", "urls": ["https://a.test/foo"]}
  ]
  }
</script>


<!-- Prettier 2.6 -->
<script type="speculationrules">
  {
   "prerender": [
  {"source": "list", "urls": ["https://a.test/foo"]}
  ]
  }
</script>

<!-- Prettier 2.7 -->
<script type="speculationrules">
  {
    "prerender": [{ "source": "list", "urls": ["https://a.test/foo"] }]
  }
</script>
```

### Vue

#### Allow formatting for Vue template expression written in TypeScript ([#12584](https://github.com/prettier/prettier/pull/12584) by [@sosukesuzuki](https://github.com/sosukesuzuki))

<!-- prettier-ignore -->
```vue
<!-- input -->
<script setup lang="ts">
let x: string | number = 1
</script>

<template>
  {{ (x      as      number).toFixed(2) }}
</template>

<!-- Prettier 2.6 -->
<script setup lang="ts">
let x: string | number = 1
</script>

<template>
  {{ (x      as      number).toFixed(2) }}
</template>

<!-- Prettier 2.7 -->
<script setup lang="ts">
let x: string | number = 1;
</script>

<template>
  {{ (x as number).toFixed(2) }}
</template>
```

#### Infer Stylus parser for Vue SFC style block ([#12707](https://github.com/prettier/prettier/pull/12707) by [@lsdsjy](https://github.com/lsdsjy))

`<style lang="stylus">` blocks in Vue SFCs can be processed by the appropriate plugin if any.

#### Avoid printing attribute per line in Vue SFC blocks ([#12895](https://github.com/prettier/prettier/pull/12895) by [@sosukesuzuki](https://github.com/sosukesuzuki))

<!-- prettier-ignore -->
```vue
<!-- Input (singleAttributePerLine: true) -->
<script lang="ts" setup>
</script>

<!-- Prettier 2.6 -->
<script
 lang="ts"
 setup
>
</script>

<!-- Prettier 2.7 -->
<script lang="ts" setup>
</script>
```

### Angular

#### Fix shorthand properties formatting ([#12993](https://github.com/prettier/prettier/pull/12993) by [@sosukesuzuki](https://github.com/sosukesuzuki), [@fisker](https://github.com/fisker))

```html
<!-- Input -->
<ng-container *ngTemplateOutlet="someTmpl; context: { app }"></ng-container>

<!-- Prettier 2.6 -->
<ng-container
  *ngTemplateOutlet="someTmpl; context: { app: this.app }"
></ng-container>

<!-- Prettier 2.7 -->
<ng-container *ngTemplateOutlet="someTmpl; context: { app }"></ng-container>
```

### GraphQL

#### Add support for printing SchemaExtension nodes ([#12519](https://github.com/prettier/prettier/pull/12519) by [@trevor-scheer](https://github.com/trevor-scheer))

<!-- prettier-ignore -->
```graphql
# Input
extend schema { subscription: Subscription }
extend schema @directive

# Prettier 2.6
N/A - throws error

# Prettier 2.7
extend schema {
  subscription: Subscription
}
extend schema @directive
```

#### Fix single line and empty description formatting ([#12608](https://github.com/prettier/prettier/pull/12608) by [@chimurai](https://github.com/chimurai), [@fisker](https://github.com/fisker))

<!-- prettier-ignore -->
```graphql
# Input
""" Customer """
type Person {
  name: String
}

""""""
type Person {
  name: String
}

# Prettier 2.6.2
"""
 Customer
"""
type Person {
  name: String
}

"""

"""
type Person {
  name: String
}

# Prettier 2.6.2 (second format)
"""
Customer
"""
type Person {
  name: String
}

"""

"""
type Person {
  name: String
}

# Prettier 2.7
"""
Customer
"""
type Person {
  name: String
}

"""
"""
type Person {
  name: String
}
```

### CLI

#### Print the number of files need change ([#12561](https://github.com/prettier/prettier/pull/12561) by [@Harry-Hopkinson](https://github.com/Harry-Hopkinson))

```console
# Prettier 2.6
$ prettier src --check
Checking formatting...
[warn] src/fileA.js
[warn] Code style issues found in the above file(s). Forgot to run Prettier?

# Prettier 2.7
$ prettier src --check
Checking formatting...
[warn] src/fileA.js
[warn] src/fileB.js
[warn] Code style issues found in 2 files. Forgot to run Prettier?

$ prettier src --check
Checking formatting...
[warn] src/fileA.js
[warn] Code style issues found in the above file. Forgot to run Prettier?
```

#### Infer parser for `.importmap` files ([#12603](https://github.com/prettier/prettier/pull/12603) by [@fisker](https://github.com/fisker))

Format [`.importmap`](https://github.com/WICG/import-maps#import-map-processing) files as JSON files.

#### Simplify performance test ([#12682](https://github.com/prettier/prettier/pull/12682), [#12698](https://github.com/prettier/prettier/pull/12698) by [@fisker](https://github.com/fisker))

When `--debug-benchmark` or `--debug-repeat` is passed:

1. The CLI skips print code to the screen or write file
1. Set log level to `debug` automatically
