Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix TS 4.7 compatibility #3024

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