项目作者: shlomiassaf

项目描述 :
Type assertion testing library for TypeScript
高级语言: TypeScript
项目地址: git://github.com/shlomiassaf/tssert.git
创建时间: 2017-12-05T22:58:55Z
项目社区:https://github.com/shlomiassaf/tssert

开源协议:

下载


tssert is a small type assertion library for typescript.

Why?

Type assertion library for TypeScript? That’s the whole point of TypeScript, isnt it?

Well, Yes.

TypeScript does type assertion by default when it performs compilation, this is the bread and butter of TypeScript:

  1. const myStr: string = 15;

The code above will result in a design time error:

  1. Type '15' is not assignable to type 'string'.

So, just by writing our code in TypeScript we get type assertion.

But, what if we want to test if an expression throws a semantic error?

The term “Type assertion” in tssert is a bit different from what it means in TypeScript.
tssert takes a different appraoch, it will check for specific things like explicit semantic errors or an explicit type.

Where?

tssert can be used by library developers who uses mixin’s and / or complex type manipulation using generics, unions and intersections.

The typescript team uses a similar tool to test their own compiler but instead of JSDoc annotation to describe output types they create a snapshot
of the types as baseline and compare.

TSLint also uses a similar approach but instead of JSDoc annotation they use special TS like file with markers where a TSLint error should occur.

I use tssert in some of the libraries I build, libraries that contain mixin’s and user defined type insertion through plugins.
Through development I found that sometime the projected types resulted in any type, usually after TS version upgrades so I used error assertions.

How

tssser uses a declerative syntax in JSDoc format to assert an expected outcome from the TS Compiler.

Semantic error assertion

A semantic error is an error the TS compiler emits when it identifies syntax errors or type errors. We can tell tssert that we excpct an error from an expression:

  1. /**
  2. * @tssert
  3. * @tsError 2322
  4. * @loc 7
  5. */
  6. const myStr: string = 15;

If we run the code in tsc we will get:

  1. my-file.ts(6,7): error TS2322: Type '15' is not assignable to type 'string'.

Since we expect the compiler to throw a semantic error, number 2322 (TS2322) at charecter number 7, if we run in in tssert we will not get an error.

Character position is always relative to the line it refers to starting from 1 (base 1)`.

We can also expect an exact match for the text message:

  1. /**
  2. * @tssert THIS IS AN OPTIONAL MESSAGE TO INCLUDE WITH THE ERROR
  3. * @tsError 2322
  4. * @tsErrorMsg Type '15' is not assignable to type 'string'.
  5. * @loc 7
  6. */
  7. const myStr: string = 15;

The output:

image

Now let’s change @tsError to 9999 so it will fail:
image

You can also use watch mode using -w or --watch:
0dh99vwnwy

All options used in tsc are valid in tssert

we can define multiple assertions for the same expression:

  1. /**
  2. * @tssert
  3. * @tsError 2322
  4. * @loc 7
  5. */
  6. /**
  7. * @tssert
  8. * @tsError 2352
  9. * @loc 23
  10. */
  11. const myStr: string = 15 as boolean;

we can define assertiong for multi-line expressions:

  1. /**
  2. * @tssert
  3. * @tsError 2322
  4. * @loc 3:11
  5. */
  6. const x: Promise<string> = Promise.resolve('str')
  7. .then( value => {
  8. const y: number = value;
  9. return value;
  10. });

In this exapmle @loc does not define a character position but a line and character position separated by a column; (LINE:CHAR)

The line count startes from the first expression after the JSDoc and not from the first line of the document. Like character position it is also using base 1.

Type assertion

Type assertion are built in to TypeScript so in most cases you case assert without tsssert

If you want to, you can:

  1. /**
  2. * @tssert
  3. * @tsType Promise<string>
  4. * @loc 16
  5. */
  6. Promise.resolve('str')
  7. .then( value => {
  8. const y: string = value;
  9. return y;
  10. });

q9lw1jivxk

Note that the position must be set on an expression or identifier, some positions might not return a property type.

Configuration:

Files written for tssert will throw errors in a tsc compilation so they must be in a dedicated folder.
A tsconfig file for tssert should identical to your tsc configration with 1 change, set the include
proeprty to include only the location where the test files for tssert are.

For example, if we put all files for tssert in test/types with the suffix .type-spec.ts the include
property should be [ "test/types/**/*.type-spec.ts" ]