Skip to content

Fix TS 4.7 compatibility #3024

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 12 commits into from
Jun 2, 2022
2 changes: 1 addition & 1 deletion .c8rc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"exclude": [
"{coverage,examples,media,test,test-d,test-tap,types}/**",
"*.config.cjs",
"*.d.ts"
"*.d.*(c|m)ts"
],
"reporter": [
"html",
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ts-version: [~4.4, ~4.5, ~4.6]
ts-version: [~4.4, ~4.5, ~4.6, ~4.7]
steps:
- uses: actions/checkout@v2
- run: rm .npmrc
Expand Down
2 changes: 1 addition & 1 deletion .xo-config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
},
overrides: [
{
files: '**/*.d.ts',
files: '**/*.d.*(c|m)ts',
rules: {
'import/extensions': 'off',
},
Expand Down
18 changes: 17 additions & 1 deletion docs/recipes/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ It's worth noting that with this configuration, tests will fail if there are Typ

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/avajs/ava/tree/main/examples/typescript-basic?file=source%2Ftest.ts&terminal=test&view=editor)

Create a `test.ts` file.
Create a `test.ts` file. ESM syntax works best, even if you're targeting CommonJS.

```ts
import test from 'ava';
Expand All @@ -94,6 +94,22 @@ test('fn() returns foo', t => {
});
```

You can use CommonJS syntax as well:

```ts
const test = require('ava');
```

This works whether `esModuleInterop` is enabled or not.

`import … = require()` syntax is less elegant. It's best like this:

```ts
import ava = require('ava')

const test = ava.default;
```

## Using [macros](../01-writing-tests.md#reusing-test-logic-through-macros)

Macros can receive additional arguments. AVA can infer these to ensure you're using the macro correctly:
Expand Down
2 changes: 2 additions & 0 deletions entrypoints/index.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {default} from '../index.js';
export * from '../index.js';
1 change: 1 addition & 0 deletions entrypoints/plugin.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../plugin.js'
10 changes: 5 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {TestFn} from './types/test-fn';
import type {TestFn} from './types/test-fn.js';

export * from './types/assertions';
export * from './types/try-fn';
export * from './types/test-fn';
export * from './types/subscribable';
export * from './types/assertions.js';
export * from './types/try-fn.js';
export * from './types/test-fn.js';
export * from './types/subscribable.js';

/** Call to declare a test, or chain to declare hooks or test modifiers */
declare const test: TestFn;
Expand Down
12 changes: 7 additions & 5 deletions lib/create-chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,13 @@ export default function createChain(fn, defaults, meta) {

root.meta = meta;

// Our type definition uses ESM syntax; when using CJS with VSCode, the
// auto-completion assumes the root is accessed through `require('ava').default`.
// Placate VSCode by adding a mostly hidden default property on the root.
// This is available through both CJS and ESM imports. We use a proxy so that
// we don't end up with root.default.default.default chains.
// The ESM and CJS type definitions export the chain (`test()` function) as
// the default. TypeScript's CJS output (when `esModuleInterop` is disabled)
// assume `require('ava').default` is available. The same goes for `import ava
// = require('ava')` syntax.
//
// Add `test.default` to make this work. Use a proxy to avoid
// `test.default.default` chains.
Object.defineProperty(root, 'default', {
configurable: false,
enumerable: false,
Expand Down
20 changes: 16 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,25 @@
},
"exports": {
".": {
"import": "./entrypoints/main.mjs",
"require": "./entrypoints/main.cjs"
"import": {
"types": "./index.d.ts",
"default": "./entrypoints/main.mjs"
},
"require": {
"types": "./entrypoints/index.d.cts",
"default": "./entrypoints/main.cjs"
}
},
"./eslint-plugin-helper": "./entrypoints/eslint-plugin-helper.cjs",
"./plugin": {
"import": "./entrypoints/plugin.mjs",
"require": "./entrypoints/plugin.cjs"
"import": {
"types": "./plugin.d.ts",
"default": "./entrypoints/plugin.mjs"
},
"require": {
"types": "./entrypoints/plugin.d.cts",
"default": "./entrypoints/plugin.cjs"
}
}
},
"type": "module",
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions types/test-fn.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {Assertions} from './assertions';
import type {Subscribable} from './subscribable';
import type {TryFn} from './try-fn';
import type {Assertions} from './assertions.js';
import type {Subscribable} from './subscribable.js';
import type {TryFn} from './try-fn.js';

/** The `t` value passed to test & hook implementations. */
export interface ExecutionContext<Context = unknown> extends Assertions {
Expand Down
2 changes: 1 addition & 1 deletion types/try-fn.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {Implementation} from './test-fn';
import type {Implementation} from './test-fn.js';

export type CommitDiscardOptions = {
/**
Expand Down