AVA now support ES6 by using Babel, run directly without any precompiling, this is very convenience. But for TypeScript, AVA has to precompile ts files by run tsc.
I use TypeScript in my project wechaty, run TS code directly by ts-node like this: ts-node demo.ts. This is a convenience way for developing.
If we can run TypeScript file directly by AVA, just like ava test.ts, that will be wonderful.
About this topic, there has already an issue #631 on it. I saw @sindresorhus agree that use TypeScript without precompiling is a better way.
@niieani You can already use TypeScript by precompiling it. I know it's not optimal, but it's not like anyone has done a pull request fixing this. https://github.com/avajs/ava/issues/631#issuecomment-250368210
I love AVA, because I'm a TAP fan, and AVA is based on TAP. So I tried to hack AVA to support TypeScript directly. After some study & work, I finished it finally, and in the past month, I was using it in my own project and it worked as my expected.
I'll share my idea here, and send a Pull Request later. Hope we can support TypeScript without precompiling soon.

I added a --ext ts argument parameter to CLI, then pass ext to AVA API. If ext is ts then I use TypeScript Compiler to replace the Babel Compiler, because TypeScript is the superset of ES6/7.
Add CLI Arg: --ext/-e
In order to support TypeScript without precompiling, first, we need to add a CLI args to support that. I use the name --ext and the alias -e for this, like ava -e ts. Set the ext automatically is considered, but I think maybe it should be done later. If set ext automatically, then we can just run TS tests by ava test.ts
Get Test Files from ava-files
AVA use a submodule ava-files to get all test files list. It had to be modified to support the ext parameter. I use exts in the ava-files module and it is an Array type, that's for the future support of multiple file extensions.
new API options: ext
in API call, we get file extension name from options.ext, pass it to AvaFiles/CachingPrecompiler/Watcher.
Add a Switcher between Babel with TypeScript
AVA compile ES6 by Babel in CachingPrecompiler, so we could compile TypeScript here. If the file extension is set to ts, then CachingPrecompiler will use a new module extTs to compile the source.
Introduce a new Module: extTs(lib/ext/ts.js)
For ts file extension, the compiler module ext/ts.js will be loaded. In the furture, other extension could modulize their own compile code in different file in ext/ directory. i.e. ext/jsx.js for a new extJsx compiling module.
Enable Run TypeScript in test-worker.js
AVA use subprocess to run tests, the worker needs to register to TypeScript compiler.
Add TypeScript dependence to package.json
Make XO happy
test.ts:
import { test } from 'ava'
test('AVA run TypeScript without tsc', t => {
let i: number = 42
t.is(i, <number>42, 'meaning of life')
})
Run:
$ ava --ext ts test.ts
β AVA run TypeScript without tsc
1 test passed [02:55:58]
Yeah~
There is a $142.00 open bounty on this issue. Add more on Issuehunt.
- Checkout the Issuehunt explorer to discover more funded issues.
- Need some help from other developers? Add your repositories on Issuehunt to raise funds.
Hi,
Is there any feedback or suggestion?
I want to know:
--ext / -e for AVA CLIexts a new key for AvaFile options --ext automatically? if we run ava test.ts then let ava know .ts should support typescript.looking forward to getting feedback, then I can make the Pull Request fit better.
Thanks for picking this up @zixia :)
Your proposal looks pretty good.
Some random feedback:
--ext multiple times..js files should always be included.--extension/-e CLI flag and extensions option name would be better.Got it.
I'll follow your great feedback then make the PR later. :)
Hi @sindresorhus ,
I had followed all your feedbacks and made two PRs: one is for AvaFiles, the other is for AVA.
Please notice that CI for AVA will be expected to report failure because the ava-files NPM modules do not support extensions parameter now.
All unit tests had passed in my dev box with the PR code.
Please let me know if I missed anything in PR, thanks.
@zixia this is awesome work and I'm excited to use it, but can you tell me if it works fine with the --watch flag too? Or is there more work to do for that?
@jedmao Hi buddy thanks you for like my work, and I'm sure you are a TypeScript fan like me.
In theory, I think it should work with the --watch flag, because I modified all the parts in AVA to support ts, including Watcher class and all the Watcher unit tests. But I did not test it yet, and there's possible I missed part of it. So if you find any problem with that, please let me know, and I'll get it worked.
If you want to try it before @sindresorhus merge this PR, you can pull my clone at https://github.com/zixia/ava (branch: typescript) , and also don't forget to link ava-files too: https://github.com/zixia/ava-files
Is there any update on this? I'm starting a new TS project and I really would like to use ava without compiling TS scripts first!
@zixia amazing work so far!
@patrick91 Thanks!
AVA decide to re-design the total code structure of how to use Babel, which delayed the TypeScript support progress.
@patrick91 (and anyone else coming across this thread) β I've been getting into Typescript a lot recently, and had some trouble getting a lot of the packages I wanted to use working together.
I spent a little time starter project which I think it might accomplish what you're looking for: es7-typescript-starter
tsconfig.json properly (so tooling/build/test settings match)main (commonjs) and module (es6 module) output formatsI'd love input/feedback on how it could be improved, especially when AVA restarts work on this issue.
@novemberborn I know I can do tsc && ava, but that won't work with --watch, will it? Is there a solution to make it work with watch?
@lukescott you can add "compileOnSave": true to your tsconfig.json if you use an editor that recognizes it. You can also change your watch/dev run script to be something like tsc -w & ava --watch so tsc will watch in the background while you run ava watch.
I think ava is super interesting but I have not replaced mocha over the typescript issue so the suggestion is not in use for me.
Ah, got it. So I need need to run them separately. Tsc will watch and save files, which Ava will pick those up. It's too bad there isn't a way to do a single watcher and have it all happen in memory.
Yep, I've been waiting for the same feature.
The plan is here, but there hasn't been progress on that lately: https://github.com/avajs/ava/blob/master/docs/specs/001%20-%20Improving%20language%20support.md
@lukescott for watch, you can do this:
https://github.com/unional/color-map/blob/master/scripts/watch.js
'use strict';
const cp = require('child_process');
let ava;
cp.spawn('tsc', ['-w'], { shell: true })
.stdout.on('data', (data) => {
if (!ava) {
ava = cp.spawn('ava', ['-w'], {
stdio: 'inherit',
shell: true
})
}
const text = data.toString()
process.stdout.write(text)
if (/.*Compilation complete/.test(text)) {
let lint = cp.spawnSync('npm', ['run', 'lint'], {
stdio: 'inherit',
shell: true
})
if (lint.status === 0) {
cp.spawnSync('npm', ['run', 'build-commonjs'])
}
}
})
The plan is here, but there hasn't been progress on that lately: https://github.com/avajs/ava/blob/master/docs/specs/001%20-%20Improving%20language%20support.md
Has there been any work on this since then?
babel has recently merged a PR that allows to parse typescript, so maybe soon enough we will be able to use ava for typescript via babel :)
Looking forward it, or I have to consider other solutions like tap which had already supported the TypeScript(https://github.com/tapjs/node-tap/issues/313) and Concurrency.
If we can run TypeScript through Babel then yea we can land some sort of support for that. Though you'd still need the equivalent to babel-register to load TypeScript source files.
With TypeScript support in babel, wouldn't babel-register (or what ever Ava uses) work? I would imagine babel adding the .ts extension w/ native support.
I came to this thread/issue while trying to use Ava's --watch feature with TypeScript. @tomdavidson's suggestion of tsc --watch & ava --watch works well enough as an intermediate solution for anyone who wants to _watch_ their TypeScript code for changes and rerun those tests.
If anyone is interested, the solution @adieuadieu mentioned (from @tomdavidson) is what typescript-starter uses right now.
I'm closing this issue since it's not directly actionable.
Our plan for making AVA precompiler-agnostic can be found here: https://github.com/avajs/ava/blob/master/docs/specs/001%20-%20Improving%20language%20support.md βΒ we'll need help achieving that.
Further, we'd be willing to support TypeScript test files sooner if we can run them through our existing Babel infrastructure.
It's a pity that we still have no workaround for this after waiting almost a year...
@zixia well there are workarounds, but no proper solution, correct. Work on AVA is volunteer driven, so sometimes it just takes the time it takes.
How difficult would be it be to just add the "extension" whitelist option? It seems like that plus ts-node/register in the require config stanza would be sufficient to make this possible.
Just adding the extension support makes it quite hard to understand which of AVA's behaviors is actually available, and as you say it requires further customizations to make the tests work. We want to land first-class support for TypeScript. We know how, but the work hasn't been done yet.
I want to vote on this feature!
I know this is an old issue, but I needed the same thing, since a prior build step can be quite ugly.
So I quickly created ava-ts. Give it a try and leave feedback if you want :)
@andywer You are awesome!
@andywer - super cool! That's epic.
I've already switched though: https://shift.infinite.red/switching-from-ava-to-jest-for-typescript-a6dac7d1712f
Sorry :(
@GantMan Thx. Pity, though! Would you mind mentioning ava-ts in your blog post? :)
Btw, thanks for all the great responses. Feel free to spread the word or π the repo, it feels a bit disregarded π
Added!!! And call-to action to star the repo added as well. Great work. Might see you cool kids again later. It seems the curse of JavaScript is that I have to switch libs as soon as I feel comfortable with them. π
@novemberborn Would you consider linking to ava-ts in the TypeScript recipe for the time being? I think that is where most folks will look for help and it makes using AVA with TS noticeably easier.
Hey @andywer! I've been thinking about this, and whilst I'm not adverse to linking to it I'd like to figure out an actionable plan to better support TypeScript directly, so we don't have to promote a fork for too long.
Following up on my earlier comment: https://github.com/avajs/ava/issues/1109#issuecomment-326801788
Further, we'd be willing to support TypeScript test files sooner if we can run them through our existing Babel infrastructure.
Here's what I think we can do pretty soon, which would provide minimal support for TypeScript. I'd like people's feedback on whether this would suit their needs.
I'm assuming people are OK with using ts-node/register for on-the-fly test file and source file compilation. The reason we didn't want to support .ts file extensions before is that AVA doesn't know not to precompile them using Babel. However we're talking about disabling Babel altogether in (amongst other issues) https://github.com/avajs/ava/issues/1556:
There's something to be said for separating AVA's file manipulations from syntax transforms. The
babeloption could refer to syntax transforms only, while we have a separatetranspileEnhancementsoption. This would supersede the currentpowerAssertoption.Since we're still looking to integrate source transpilation and also support TypeScript, it makes sense (at least to me) that the enhancements are controlled separately.
https://github.com/avajs/ava/issues/1556#issuecomment-340003308
With #1556 out of the way we could add support for an extensions option. AVA would treat matched files with the configured extensions as test files. It won't precompile them so it won't break on .ts files. ts-node/register then takes care of transpilation.
Of course you could still precompile all files like you do now. It'd love for AVA to compile .ts files itself but that'd be follow-up work.
Ideally you wouldn't need to configure extensions either but currently when the globbing rules match directories we look for .js files specifically. I'm sure there are possible improvements but that's for later.
What do folks think about this approach?
ts-node support sounds like a convenient approach, there are probably other language-node libs that may work the same.
For registering ts-node itself, would you use "require" in the package.json#ava?
Since --require was depreciated from the cli options, is it a limiation now that you can't seem scope what to require for what?
For example say I didn't want to use ts-node or some global browser env for every test I want to use in ava:
"scripts": {
"test:ts-node": "ava --require helpers/ts-node.js src/**/**.ava.ts",
"test:ts-browser": "ava --require helpers/ts-browser-env.js src/**/**.ava-browser.tsx"
}
Babel 7 has support for TypeScript, so all you have to do is use the typescript preset. I've found that enums and namespaces are not supported though. Everything else seems to work great.
In the latest betas they've changed from babel-core to @babel/core, and all the packages are now namespaced under @babel. All the plugins with the word "transform" have been changed to "proposal" and all the config options need to start with @babel/, such as "@babel/env" instead of just "env".
For registering ts-node itself, would you use "require" in the package.json#ava?
Since --require was depreciated from the cli options, is it a limiation now that you can't seem scope what to require for what?
@impaler pending 1st class support in AVA itself I think that's how it'd play out, yes. You disable AVA's Babel-powered treatment of test files and rely on language-node libs to transpile test files.
Babel 7 has support for TypeScript, so all you have to do is use the typescript preset. I've found that enums and namespaces are not supported though. Everything else seems to work great.
@lukescott does it do type checking as well, or does it just remove the syntax annotations? Regardless, it might be an option. With what I'm suggesting AVA would still default to applying Babel to test files and it's up to you to ensure Babel doesn't choke. So once we switch to Babel 7 you could go this route if it's the right fit for your project.
I'm not sure how babel has implimented typescript support, but if it's just removing the syntax annotations then some people will run into issues with type metadata. This could potentionally mess with IoC implementations.
I would strongly favor using a language-node package to transpile tests.
It just removes the TypeScript specific syntax, similar to what it has already done with Flow. So far it has greatly simplified my build process as I donβt have to pre-process with tsc. I just run TypeScript in Atom for all the type checking.
I would imagine that the typescript preset would at least allow you to run Ava with TypeScript code. You can use tsc to validate the types are correct.
Re: @lukescott's comment, according to the babel-plugin-transform-typescript docs, import = and export = aren't supported either. This, combined with lack of enums and namespaces, means I'd really be loathe to use it in place of something like ts-node.
FWIW, a number of test tools use ts-node already (NYC, Mocha), so it's a pretty well-established workflow when testing using TS.
Any recent activity on this? I'm choosing a test runner for a new application, and good TypeScript support is an important part of that decision.
@jonahbron As ava uses Babel 7 it should support TypeScript if you use @babel/plugin-transform-typescript. There are a few caveats though so it depends on whether you are using any of the unsupported features.
As ava uses Babel 7
To clarify, that's the 1.0 beta releases.
Architecturally we're in a pretty decent place to implement built-in TypeScript compilation. It's still a big chunk of work though. Soβ¦ any volunteers? π
We can also start adding support for test file extensions that bypass the Babel pipeline, so that'd be a way to use AVA with the TS register hook. That has some performance issues of course, so it may not be right for some (or most) projects.
Any updates on Typescript support?
Hey @shirtleton I'm working on making it so you can configure ava to use file extensions like .jsx or .ts. It's almost done, were just adding tests and cleaning up a bit of the code written for it, so should be soon. Here is the PR for reference #1746 Thanks!
Any news about this?
@ShinDarth it's working with ts-node module installed and config shown here https://github.com/avajs/ava/blob/master/docs/recipes/typescript.md (first TS recipe)
Yes, AVA can now be configured to recognize the .ts file extension. With TypeScript 3 the build tooling has improved a lot, so I think we can make AVA compile a TypeScript project, without requiring ts-node.
I'd like to port some of my own projects to TypeScript so I'd really like to see improved TypeScript support in AVA. For now though my priority is getting the 1.0 release out.
If anybody would like to help out with this project please give me a shout.
It's worth mentioning that AVA 1.0 is now out :confetti_ball:. You can use typescript with this recipe. I've been using it in production for a while now, and it works great. This issue can be closed.
@btkostner ts-node is _not_ a drop-in replacement for tsc, even though many people think so. Running ts-node/register will give most people a similar experience, but each time there is a typescript release, ts-node potentially has compile errors again.
IMO ava should be able to run this itself.
The latest Jest 24 release supports TypeScript via @babel/preset-typescript
@0maxxam0 has funded $2.00 to this issue.
@issuehunt has funded $140.00 to this issue.
Should we close this and make a new issue that better summarizes the current state of affairs?
Right now, the included recipe does a pretty-okay job of providing TypeScript support via ts-node.
Current downsides are:
-- Cannot be used with compileEnhancements
-- Extra overhead for compiling tests & any dependencies for each test file. (This ends up being a _huge_ performance hit if you need to run ava with --serial -- in my test suite, this adds about ~4sec to each test file, completely destroying any performance benefits that Ava might have over Mocha)
As an alternative to ts-node (even if we address the above drawbacks) , it seems like there's a good opportunity to also allow users to use @babel/preset-typescript instead. This preset has quickly gained a ton of popularity in frontend projects, and is small enough that Ava could provide it as an "out of the box" solution that builds on Ava's existing Babel support.
@schmod ts-node works, but it's not perfect and it requires various boilerplate config. @novemberborn and I would ideally prefer as close to zero config TypeScript support as possible. Our goal has always been for AVA to just work in the common cases, and TypeScript can be considered common these days. We also have extra incentive to push this as we both have started to use TypeScript ourselves.
Last time I chatted privately with @novemberborn about this, we discussed adding a config property like typescript: true, ava.babel.typescript: true, typescript.usingBabel: true, and eventually integrating the TypeScript compiler itself.
@sindresorhus β I'd certainly be happy with any of those options!
ya, last i tried, a good debug experience still essentially requires that boilerplate (e.g. disabling compile enhancements) otherwise sourceMaps get real weird. i'm not sure i've tried w/ babel7 yet though, to be fair. disabling compile enhancements + ts-node still allow me to use breakpoints naturally in my editor and use the launch config recipes π¨βπ³ without a headache.
ts-node is a dumpster fire for anything beyond a very simple setup. Harsh, but fair.
I'd like to get the Rollup org on Ava across the board, but TypeScript support is a major blocker. What's the chance that this is still something that's getting consideration?
Just a question here. What's so wrong with pre-compiling? Why does a testing framework need to be concerned with TypeScript beyond providing types? Wouldn't it introduce more complexity into ava?
Well, that was (partially) a secret of Jest's success. Would happily consider Ava if it has built-in TS support.
If testing framework supports it - it automatically unlocks 1-click to run test in IDEs (e.g Jetbrains) which is a big DX win
What about separation of concerns? Isn't that a DX win in the long term?
My current thinking (once the extraction of Babel matures) is to support a TypeScript integration which knows how to load the pre-compiled files. So you specify src/test.ts and it loads build/test.js.
I'm less convinced of the need to compile the entire project.
What do folks think?
Just a question here. What's so wrong with pre-compiling? Why does a testing framework need to be concerned with TypeScript beyond providing types? Wouldn't it introduce more complexity into ava?
Simply put: it's yet more friction for the adoption of Ava by TypeScript developers, where it doesn't exist elsewhere in other tools. As was mentioned by @kirillgroshkov, Jest has for a long time supported worriless, (relatively) frictionless TypeScript support. Yes, it would introduce more complexity. Supporting a larger user base tends to do that.
Well, that was (partially) a secret of Jest's success. Would happily consider Ava if it has built-in TS support.
Agreed.
What about separation of concerns? Isn't that a DX win in the long term?
I would argue that DX is made worse. Separation of concerns works very well in many aspects of our trade, but this is not one.
What do folks think? @novemberborn
Jest has really set the gold standard here. If there's different path from what Jest has done as a means to accomplish frictionless support of TypeScript, I'm all for it. But increased friction is a very hard sell for any team/org. I'd argue Ava is better than Jest in a myriad of ways, but forcing additional build steps is not appealing to folks. Config is generally fine, as even Jest requires being told about how it needs to hand TS (https://github.com/rollup/rollup-pluginutils/blob/master/jest.config.js)
once the extraction of Babel matures
Is there a timeline on this? If this is an unknown quantity, that's going to make for another point on a hard sell.
as even Jest requires being told about how it needs to hand TS
I think that's outdated. If one is using babel with jest, everything is automagic, if babel is set-up correctly. Only when using ts-jest, you need to add the three lines (or the single `preset: 'ts-jest') iirc.
What I want to say with that is, yes, setup is fine (in terms of friction), and it can be as easy as flipping a switch, as suggested above.
@novemberborn, I really love that idea as a stop gap--it would make most of my projects just work, even if i had to turn off Babel and compile enhancements still. However, it does however have holes. First, many people compile to a different output dir, so a sibling is file isn't always an option. next, noEmit compiler flag is used often in projects--especially projects with some ui (which Ava generally doesn't support atm). I think the "detect ts file > Babel with ts plugin > run" pipeline will probably be most fruitful, so long as source maps work. Now that were on Babel 7, I'm actually unclear on what the barriers to this are beyond file type detection :thinking:
Regarding extracting Babel: the goal is for AVA to work with just Node.js, without any compilation. But, you'll be able to install @ava/babel and enable it in AVA's configuration. That package would take care of compiling test & helpers (for AVA 2.0 compatibility) and can then be improved to take on source compilation as well.
As alluded to by others, you could use Babel to strip TypeScript.
But I'd love to also have a separate @ava/typescript package that can be integrated in the same way. One mode of operation would be to load test files from a TS output directory, but like with @ava/babel it could take on TypeScript compilation as well.
I'm hoping to have a decent chunk of time to work on the Babel stuff, and other changes for an AVA 3 release as work breaks up for the holidays.
Does this work with TS or not?
Babel compilation has now been moved into a separate package, which means we can now do the same for TypeScript. See references to https://github.com/avajs/ava/blob/master/lib/babel-manager.js and beyond for ideas on how this might work.
Ultimately this should be hosted at https://github.com/avajs/typescript so if you're keen to work on this give me a shout and I can get all that set up.
Rudimentary support is now in progress at https://github.com/avajs/typescript/pull/1. See also https://github.com/avajs/ava/pull/2379.
Example usage at https://github.com/novemberborn/got/pull/1.
This will go out in AVA 3.1; beyond that I'll create some issues in the https://github.com/avajs/typescript repository for where we can take this next.
AVA 3.1 is now available: https://github.com/avajs/ava/releases/tag/v3.1.0
I've opened some issues to track enhancements here: https://github.com/avajs/typescript/issues
Thank you all for your interest!
Most helpful comment
Yes, AVA can now be configured to recognize the
.tsfile extension. With TypeScript 3 the build tooling has improved a lot, so I think we can make AVA compile a TypeScript project, without requiringts-node.I'd like to port some of my own projects to TypeScript so I'd really like to see improved TypeScript support in AVA. For now though my priority is getting the 1.0 release out.
If anybody would like to help out with this project please give me a shout.