You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ts-node swallows errors for non-executed files (ambient type declarations, .d.ts, referenced but not required .ts) #853
exportdeclareinterfaceFoo{}also,let's add some garbage here // invalid Typescript, this should not compile
example.spec.ts:
import{Foo}from'.';describe('example',()=>{it('should not compile',()=>{constfoo: Foo={};});});
Compilation of this project with tsc fails:
> tsc
index.d.ts:3:10 - error TS1005: ';' expected.
3 also, let's add some garbage here // this should not compile
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index.d.ts:3:61 - error TS1002: Unterminated string literal.
3 also, let's add some garbage here // this should not compile
Found 2 errors.
But running the test with ts-node succeeds:
> mocha --require ts-node/register *.spec.ts
example
✓ should not compile
1 passing (13ms)
Expected behaviour: the test should fail with the same errors as tsc.
I am also facing this issue and find it strange that it doesn't report on errors. Were you able to make it work or if you moved to another solution can you share it.
This sounds like a reasonable enhancement request / bug report for ts-node. The following is probably obvious, but in the interest of precision, I tried to explain exactly how we should do this.
ts-node needs to roughly match the behavior of node, in terms of throwing errors. When node requires a JavaScript file, if that file has a syntax error, it is thrown. It can be caught just like any other error, but usually this means you want your program to terminate because something is wrong.
If one JavaScript file requires a bunch of other files -- like when loading a large library -- any syntax errors bubble up the call stack. From the caller's perspective, an error is thrown when anything in the require() tree has an error.
Once a file is successfully in node's require() cache, it will never be parsed or executed again, so there's no longer a possibility for errors to be thrown.
We can do exactly the same in TS. If one .ts file causes the TS compiler to load a bunch of other TS files, (.ts, .d.ts, types and/or runtime code) and if any of them have an error (syntactic or semantic) then the require() call should throw.
changed the title [-]ts-node ignores errors in ambient type declarations[/-][+]ts-node swallows errors for non-executed files (ambient type declarations, .d.ts, referenced but not required .ts)[/+]on Apr 18, 2020
@alexeevg I renamed the issue title to be a bit more encompassing of the possible swallowed errors.
It's possible this behavior is intentional. If someone passes ts-node --files then it'll load all .ts files eagerly at the start, and any type errors in the whole codebase will cause it to throw an error immediately when you try to load the first .ts file. Perhaps this was avoided on purpose; I'm not sure.
@cspotcode using --files doesn't seem a valid use case for most people. Like highlighted in the readme. Most of the people the application is started by running only the root file ts-node server.ts. And all dependencies are resolved.
Also to add, I have include in my tsconfig but still no typescript errors
@hisabimbola I'm not disagreeing, but we need to figure out exactly how to implement this change, which means figuring out every possibility. Even if most people don't use --files, we need to figure out exactly how it will change and how it will behave. This change will make many projects immediately throw type errors before anything loads, whether or not they're using --files.
--files refers to "include" as well. It means we will use both your "files" and "include" arrays. When you don't specify --files, we set the "files" and "include" arrays to [], then add files to the compiler one at a time as they are require()d.
--files can greatly improve performance in some cases, because it enables the compiler to typecheck once for the whole program, instead of re-doing the typecheck for each require()d file.
other-file.ts is never executed. However, the compiler will still load it. Supposing ./other-file.ts loads ./another.ts, which loads ./something-else.ts. If ./something-else.ts has a type error, then it will be thrown as soon as index.ts is loaded, even though all those other files never executed.
I still think this change is good, but it's bigger than it might seem at first glance.
@hisabimbola@alexeevg I made #1018 that should implement the behavior you want, but it's completely untested. I'd appreciate if you can test it, see if it reports the diagnostics you expect, see if it changes performance.
Activity
alexeevg commentedon Jul 18, 2019
Running the example under debugger, I can see that after the
service.getEmitOutput(fileName)call the compiler API produces the errors:But they are ignored,
ts-nodeonly reports errors forfileName.hisabimbola commentedon Apr 18, 2020
Hello @alexeevg
I am also facing this issue and find it strange that it doesn't report on errors. Were you able to make it work or if you moved to another solution can you share it.
cspotcode commentedon Apr 18, 2020
This sounds like a reasonable enhancement request / bug report for
ts-node. The following is probably obvious, but in the interest of precision, I tried to explain exactly how we should do this.ts-node needs to roughly match the behavior of node, in terms of throwing errors. When node requires a JavaScript file, if that file has a syntax error, it is thrown. It can be caught just like any other error, but usually this means you want your program to terminate because something is wrong.
If one JavaScript file requires a bunch of other files -- like when loading a large library -- any syntax errors bubble up the call stack. From the caller's perspective, an error is thrown when anything in the require() tree has an error.
Once a file is successfully in node's
require()cache, it will never be parsed or executed again, so there's no longer a possibility for errors to be thrown.We can do exactly the same in TS. If one
.tsfile causes the TS compiler to load a bunch of other TS files, (.ts, .d.ts, types and/or runtime code) and if any of them have an error (syntactic or semantic) then therequire()call should throw.[-]ts-node ignores errors in ambient type declarations[/-][+]ts-node swallows errors for non-executed files (ambient type declarations, .d.ts, referenced but not required .ts)[/+]cspotcode commentedon Apr 18, 2020
@alexeevg I renamed the issue title to be a bit more encompassing of the possible swallowed errors.
It's possible this behavior is intentional. If someone passes
ts-node --filesthen it'll load all.tsfiles eagerly at the start, and any type errors in the whole codebase will cause it to throw an error immediately when you try to load the first.tsfile. Perhaps this was avoided on purpose; I'm not sure.hisabimbola commentedon Apr 18, 2020
@cspotcode using
--filesdoesn't seem a valid use case for most people. Like highlighted in the readme. Most of the people the application is started by running only the root filets-node server.ts. And all dependencies are resolved.Also to add, I have
includein my tsconfig but still no typescript errorscspotcode commentedon Apr 18, 2020
@hisabimbola I'm not disagreeing, but we need to figure out exactly how to implement this change, which means figuring out every possibility. Even if most people don't use
--files, we need to figure out exactly how it will change and how it will behave. This change will make many projects immediately throw type errors before anything loads, whether or not they're using--files.--filesrefers to"include"as well. It means we will use both your"files"and"include"arrays. When you don't specify--files, we set the"files"and"include"arrays to[], then add files to the compiler one at a time as they arerequire()d.--filescan greatly improve performance in some cases, because it enables the compiler to typecheck once for the whole program, instead of re-doing the typecheck for eachrequire()d file.If someone has the following
index.ts:other-file.tsis never executed. However, the compiler will still load it. Supposing./other-file.tsloads./another.ts, which loads./something-else.ts. If./something-else.tshas a type error, then it will be thrown as soon asindex.tsis loaded, even though all those other files never executed.I still think this change is good, but it's bigger than it might seem at first glance.
cspotcode commentedon Apr 20, 2020
@hisabimbola @alexeevg I made #1018 that should implement the behavior you want, but it's completely untested. I'd appreciate if you can test it, see if it reports the diagnostics you expect, see if it changes performance.