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
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
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
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
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
@@ -0,0 +1,2 @@
export {default} from '../index.js';
export * from '../index.js';
1 change: 1 addition & 0 deletions entrypoints/plugin.d.cts
@@ -0,0 +1 @@
export * from '../plugin.js'
10 changes: 5 additions & 5 deletions index.d.ts
@@ -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
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
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
@@ -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
@@ -1,4 +1,4 @@
import type {Implementation} from './test-fn';
import type {Implementation} from './test-fn.js';

export type CommitDiscardOptions = {
/**
Expand Down