Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asserting that TypeScript should fail to type check some example code

When I write a TypeScript library with generic constraints, I'd like to be able to specify tests of code that should type check and code that should not (because, say, I want to make sure the type checker is catching things that wouldn't satisfy a constraint correctly).

I haven't found a solution in conventional unit testing libraries (since the tests for failures wouldn't compile in the first place). I think I saw some examples of this deep in the TypeScript test suite where they either used file naming or comments to indicate assertions, but I can't find them now, and I couldn't unravel how the test runner worked for such a large project anyway. Googling is hard too: every combination of terms I've thought about brings back links about things like type guards or bug reports about TypeScript itself.

I know I could rig up a bash script that just runs tsc over the files and asserts that they fail, but I'd prefer the ability to match on specific compilation failures if possible. Any ideas?

like image 578
AndrewO Avatar asked Jul 05 '18 14:07

AndrewO


2 Answers

For tsc, use @ts-expect-error.

Snippet from @jmattheis example above:

// @ts-expect-error
Abc.TestFunc(true);
like image 79
michael Avatar answered Nov 09 '22 18:11

michael


You can use Microsoft/dtslint for this. After you went through the setup you can write test files like this:

index.d.ts:

// TypeScript Version: 2.1

declare module 'Abc' {
    function TestFunc(s: string): undefined;
}

test.ts:

import Abc from 'Abc';

// $ExpectError
Abc.TestFunc(true);

// $ExpectError
Abc.TestFunc(5);

Abc.TestFunc("it is a string");

Now when you run the dtslint cli tool no error will be returned, because all errors are expected. If f.ex. an error is not commented with $ExpectError (e.g. Abc.TestFunc(true);) then the dtslint tool fails with a message:

Error: C:/stackoveflow/test.ts:3:14
ERROR: 3:14  expect  TypeScript@next compile error:
Argument of type 'true' is not assignable to parameter of type 'string'.

    at I:\..\dtslint\bin\index.js:101:19
    at Generator.next (<anonymous>)
    at fulfilled (I:\..\dtslint\bin\index.js:5:58)
    at <anonymous>
like image 6
jmattheis Avatar answered Nov 09 '22 18:11

jmattheis