Tom MacWright

2025@macwright.com

An ast-grep rule requiring you to await vitest expectations

See the last ast-grep rule I posted for context here… this rule is targeted at cases in vitest in which we had tests like

it('loads', () => {
  expect(loader()).resolves.toEqual([])
})

This introduced a subtle bug in tests because there's no await keyword, so we're not waiting for the loader() method to finish before moving on with other test cases. The proper way to write that test is:

it('loads', async () => {
  await expect(loader()).resolves.toEqual([])
})

Vitest 3 autodetects this bug, but Val Town haven't upgraded yet. So in the meantime, this ast-grep rule creates a nice guardrail.

id: require-expect-await-rejects
language: tsx
severity: error
rule:
  pattern: expect($$$ANY).rejects
  not:
    inside:
      kind: await_expression
      stopBy: end

Yes, typescript-eslint has a rule called require-await that does just this. But we dropped Eslint (and Prettier) for Biome last year and I'm not looking back. The old eslint setup was both slow and fragile – it would break every time we bumped TypeScript versions. The Biome team is planning to implement type inference in 2.0, so maybe we'll get all the power of something like typescript-eslint eventually!