typescript-runtime-type-benchmarks icon indicating copy to clipboard operation
typescript-runtime-type-benchmarks copied to clipboard

feat: add validate-value

Open RA80533 opened this issue 4 years ago • 16 comments

validate-value

RA80533 avatar Dec 28 '20 04:12 RA80533

@RA80533 wanna rebase that with all of the recent changes and try again?

moltar avatar Dec 28 '20 05:12 moltar

Seems to be the build step is failing. Is it working on your local?

npm run test:build

Does this pass?

moltar avatar Dec 28 '20 06:12 moltar

The import for expect-type should be removed.

https://github.com/moltar/typescript-runtime-type-benchmarks/blob/8dc8934c57cbdd22aa85f889f4889d25ca6813e5/test/abstract.test.ts#L2

RA80533 avatar Dec 28 '20 06:12 RA80533

The import for expect-type should be removed.

https://github.com/moltar/typescript-runtime-type-benchmarks/blob/8dc8934c57cbdd22aa85f889f4889d25ca6813e5/test/abstract.test.ts#L2

Why? It's being used for a type test.

moltar avatar Dec 28 '20 06:12 moltar

Woah, I'm nuts. I thought I saw a commit that removed it as a dependency.

RA80533 avatar Dec 28 '20 06:12 RA80533

The actual type test fails. It seems the test was written expecting it to evaluate at run-time but it actually evaluates the test at compile-time.

// %inferred-type: any
res;

res does not conform to the type of DATA at compile-time because it is of type any.

https://github.com/moltar/typescript-runtime-type-benchmarks/blob/91745cbea0d11d7c6ba441e4b47a9d3ee49dbfe4/test/abstract.test.ts#L31

RA80533 avatar Dec 28 '20 06:12 RA80533

Yeah the type tests are compile time only, as there is no way to test types at runtime.

moltar avatar Dec 28 '20 06:12 moltar

Before your issue, I didn't have the build tests at all. It was just running jest. But I added the build step to GH Actions to catch type errors too. But this test was there before and it did actually fire via jest when there were issues.

moltar avatar Dec 28 '20 06:12 moltar

The error we're actually seeing is a result of the expectation failing due to the type mismatch. It's not very clear on its own but, when we inspect the function signature for the failed expectation itself, the argument MISMATCH_0: never provides that bit of information.

Screen Shot 2020-12-28 at 1 25 45 AM

RA80533 avatar Dec 28 '20 06:12 RA80533

When I did this PR originally, I removed line 31 in order to get the tests to pass because of the failed expectation.

RA80533 avatar Dec 28 '20 06:12 RA80533

https://github.com/moltar/typescript-runtime-type-benchmarks/blob/73b6b8fc66c961f3a8bdc4655fe3a30782caaf1f/cases/abstract.ts#L6

Annotating data as type Data rather than any allows the expectation to pass.

RA80533 avatar Dec 28 '20 06:12 RA80533

Jest already runs the TypeScript compiler through ts-jest so the extra workflow step of calling tsc --noEmit via test:build is redundant.

RA80533 avatar Dec 28 '20 06:12 RA80533

Jest already runs the TypeScript compiler through ts-jest so the extra workflow step of calling tsc --noEmit via test:build is redundant.

Not redundant, because not all code is tested. As evident from your original issue - the benchmarking code was failing after an automatic upgrade.

https://github.com/moltar/typescript-runtime-type-benchmarks/blob/73b6b8fc66c961f3a8bdc4655fe3a30782caaf1f/cases/abstract.ts#L6

Annotating data as type Data rather than any allows the expectation to pass.

But the point of having it as any is so that we can test if the type casting works correctly after validation.

input: any output: Data


I'll take a look at your PR code shortly.

moltar avatar Dec 28 '20 07:12 moltar

Ok, so the problem is that isValid method is not type guarding at all. It just returns a boolean. The data is still any.

Per the docs of the lib, you want to use the isTypeOf fn.

When using TypeScript, you may even specify a generic type parameter, and use the function as a type guard. Also it is recommended to use the constant values exported by validate-value instead of the string literals as above, as they are the type-safe versions of these literals:

moltar avatar Dec 28 '20 07:12 moltar

Not redundant, because not all code is tested. As evident from your original issue - the benchmarking code was failing after an automatic upgrade.

After a bit of digging, I found out why it was passing prior to my original issue. The expected behavior of ts-jest is to both type-check files and run the tests (see here), I was perplexed as to why those specific errors weren't showing up in the logs.

Jest wasn't type-checking index.ts because it was not picked up by Jest (it is not in the Jest glob nor is it included by anything in the glob). Furthermore, it wasn't counted towards any coverage metrics because it had no exports.

Per the docs of the lib, you want to use the isTypeOf fn.

Good catch—using the function with an explicit type parameter settles things down. I didn't realize types were being narrowed for expectTypeOf().

RA80533 avatar Dec 28 '20 09:12 RA80533

Jest wasn't type-checking index.ts because it was not picked up by Jest (it is not in the Jest glob nor is it included by anything in the glob). Furthermore, it wasn't counted towards any coverage metrics because it had no exports.

Yup, so that's why I added the build step as well. The index benchmark code isn't really testable.

moltar avatar Dec 28 '20 10:12 moltar