Repository: dubzzz/fast-check
Pull request #1521 (2021-02-17 21:16:01)

🔧 Enable strict mode in tsconfig
<!-- Why is this PR for? -->
<!-- Describe the reason why you opened this PR or give a link towards the associated issue. -->

## In a nutshell

Safer build

❌ New feature
❌ Fix an issue
❌ Documentation improvement
✔️ Other: *please explain*

(✔️: yes, ❌: no)

## Potential impacts

Maybe a typing issue with `scheduleSequence` but actually it would highlight a real bug.


codesandbox[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/dubzzz/fast-check/pr/1521/builds/102716) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 440eb759b268a157c1c80d5e5b20d588af153ccb:

|Sandbox| Source |
|--|--|
|[Vanilla](https://codesandbox.io/s/vanilla-g6kll)| Configuration |
|[fast-check-examples](https://codesandbox.io/s/fast-check-examples-g0sw1)| Configuration |

codecov[bot]: # [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=h1) Report
> Merging [#1521](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=desc) (440eb75) into [main](https://codecov.io/gh/dubzzz/fast-check/commit/36e9be5d0f0b7b318245c7b096147398461b0a5a?el=desc) (36e9be5) will **decrease** coverage by `0.03%`.
> The diff coverage is `90.90%`.

[![Impacted file tree graph](https://codecov.io/gh/dubzzz/fast-check/pull/1521/graphs/tree.svg?width=650&height=150&src=pr&token=fRi2fJN730)](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##             main    #1521      +/-   ##
==========================================
- Coverage   97.36%   97.32%   -0.04%     
==========================================
  Files          92       92              
  Lines        3145     3146       +1     
  Branches      611      611              
==========================================
  Hits         3062     3062              
- Misses         79       80       +1     
  Partials        4        4              
```

| Flag | Coverage Δ | |
|---|---|---|
| unit-tests | `97.32% <90.90%> (-0.04%)` | :arrow_down: |
| unit-tests-10.x-Linux | `?` | |
| unit-tests-12.x-Linux | `97.32% <90.90%> (-0.04%)` | :arrow_down: |
| unit-tests-14.x-Linux | `?` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/check/runner/Sampler.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL3J1bm5lci9TYW1wbGVyLnRz) | `93.18% <75.00%> (ø)` | |
| [src/check/arbitrary/AsyncSchedulerArbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9Bc3luY1NjaGVkdWxlckFyYml0cmFyeS50cw==) | `98.27% <100.00%> (ø)` | |
| [src/check/arbitrary/RecordArbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9SZWNvcmRBcmJpdHJhcnkudHM=) | `98.11% <100.00%> (+0.03%)` | :arrow_up: |
| [src/check/arbitrary/SubarrayArbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9TdWJhcnJheUFyYml0cmFyeS50cw==) | `95.31% <100.00%> (ø)` | |
| [src/check/model/ModelRunner.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL21vZGVsL01vZGVsUnVubmVyLnRz) | `89.58% <100.00%> (ø)` | |
| [src/check/runner/Runner.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL3J1bm5lci9SdW5uZXIudHM=) | `100.00% <100.00%> (ø)` | |
| [src/check/runner/reporter/RunExecution.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL3J1bm5lci9yZXBvcnRlci9SdW5FeGVjdXRpb24udHM=) | `94.82% <100.00%> (ø)` | |
| [src/check/arbitrary/ArrayArbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1521/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9BcnJheUFyYml0cmFyeS50cw==) | `93.54% <0.00%> (-1.08%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=footer). Last update [36e9be5...440eb75](https://codecov.io/gh/dubzzz/fast-check/pull/1521?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/check/arbitrary/AsyncSchedulerArbitrary.ts b/src/check/arbitrary/AsyncSchedulerArbitrary.ts
index f19860de..9b223d26 100644
--- a/src/check/arbitrary/AsyncSchedulerArbitrary.ts
+++ b/src/check/arbitrary/AsyncSchedulerArbitrary.ts
@@ -281,7 +281,7 @@ class SchedulerImplem<TMetaData> implements Scheduler<TMetaData> {
       );
   }
 
-  scheduleSequence(sequenceBuilders: SchedulerSequenceItem[]) {
+  scheduleSequence(sequenceBuilders: SchedulerSequenceItem<TMetaData>[]) {
     // We run all the builders sequencially
     // BUT we allow tasks scheduled outside of this sequence
     //     to be called between two of our builders
diff --git a/src/check/arbitrary/RecordArbitrary.ts b/src/check/arbitrary/RecordArbitrary.ts
index 0cde68d3..1174db5b 100644
--- a/src/check/arbitrary/RecordArbitrary.ts
+++ b/src/check/arbitrary/RecordArbitrary.ts
@@ -154,7 +154,8 @@ function record<T>(
     if (requiredKeys.indexOf(k) !== -1) updatedRecordModel[k] = requiredArbitrary;
     else updatedRecordModel[k] = option(requiredArbitrary);
   }
-  return rawRecord(updatedRecordModel as any).map((obj: { [K in keyof T]: { value: T[keyof T] } | null }) => {
+  return rawRecord(updatedRecordModel as any).map((rawObj) => {
+    const obj = rawObj as { [K in keyof T]: { value: T[keyof T] } | null };
     const nobj: { [K in keyof T]?: T[keyof T] } = {};
     for (let index = 0; index !== keys.length; ++index) {
       const k = keys[index];
diff --git a/src/check/arbitrary/SubarrayArbitrary.ts b/src/check/arbitrary/SubarrayArbitrary.ts
index beb612b8..00e08a69 100644
--- a/src/check/arbitrary/SubarrayArbitrary.ts
+++ b/src/check/arbitrary/SubarrayArbitrary.ts
@@ -37,7 +37,7 @@ class SubarrayArbitrary<T> extends Arbitrary<T[]> {
     );
   }
   generate(mrng: Random): Shrinkable<T[]> {
-    const remainingElements = this.originalArray.map((v, idx) => idx);
+    const remainingElements = this.originalArray.map((_v, idx) => idx);
     const size = this.lengthArb.generate(mrng).value;
     const ids: number[] = [];
     for (let idx = 0; idx !== size; ++idx) {
diff --git a/src/check/model/ModelRunner.ts b/src/check/model/ModelRunner.ts
index 1c3cca10..fb1ef430 100644
--- a/src/check/model/ModelRunner.ts
+++ b/src/check/model/ModelRunner.ts
@@ -54,7 +54,7 @@ const internalModelRun = <Model extends object, Real>(
   s: ModelRunSetup<Model, Real>,
   cmds: Iterable<Command<Model, Real>>
 ): void => {
-  const then = (p: undefined, c: () => undefined) => c();
+  const then = (_p: undefined, c: () => undefined) => c();
   const setupProducer: SetupProducer<Model, Real, undefined> = {
     then: (fun: SetupFun<Model, Real, void>) => {
       fun(s());
diff --git a/src/check/runner/Runner.ts b/src/check/runner/Runner.ts
index 5054dbda..9848a79c 100644
--- a/src/check/runner/Runner.ts
+++ b/src/check/runner/Runner.ts
@@ -119,7 +119,7 @@ function check<Ts>(rawProperty: IRawProperty<Ts>, params?: Parameters<Ts>): unkn
   if (rawProperty.run == null)
     throw new Error('Invalid property encountered, please use a valid property not an arbitrary');
   const qParams: QualifiedParameters<Ts> = QualifiedParameters.read<Ts>({
-    ...readConfigureGlobal(),
+    ...(readConfigureGlobal() as Parameters<Ts>),
     ...params,
   });
   if (qParams.reporter !== null && qParams.asyncReporter !== null)
@@ -135,12 +135,11 @@ function check<Ts>(rawProperty: IRawProperty<Ts>, params?: Parameters<Ts>): unkn
   const sourceValues = new SourceValuesIterator(initialValues, maxInitialIterations, maxSkips);
   return property.isAsync()
     ? asyncRunIt(property, sourceValues, qParams.verbose, qParams.markInterruptAsFailure).then((e) =>
-        e.toRunDetails(qParams.seed, qParams.path, qParams.numRuns, maxSkips, qParams)
+        e.toRunDetails(qParams.seed, qParams.path, maxSkips, qParams)
       )
     : runIt(property, sourceValues, qParams.verbose, qParams.markInterruptAsFailure).toRunDetails(
         qParams.seed,
         qParams.path,
-        qParams.numRuns,
         maxSkips,
         qParams
       );
diff --git a/src/check/runner/Sampler.ts b/src/check/runner/Sampler.ts
index 0817f095..f501ec3a 100644
--- a/src/check/runner/Sampler.ts
+++ b/src/check/runner/Sampler.ts
@@ -28,8 +28,8 @@ function streamSample<Ts>(
 ): IterableIterator<Ts> {
   const extendedParams =
     typeof params === 'number'
-      ? { ...readConfigureGlobal(), numRuns: params }
-      : { ...readConfigureGlobal(), ...params };
+      ? { ...(readConfigureGlobal() as Parameters<Ts>), numRuns: params }
+      : { ...(readConfigureGlobal() as Parameters<Ts>), ...params };
   const qParams: QualifiedParameters<Ts> = QualifiedParameters.read<Ts>(extendedParams);
   const tossedValues: Stream<() => Shrinkable<Ts>> = stream(
     toss(toProperty(generator, qParams), qParams.seed, qParams.randomType, qParams.examples)
@@ -97,8 +97,8 @@ function statistics<Ts>(
 ): void {
   const extendedParams =
     typeof params === 'number'
-      ? { ...readConfigureGlobal(), numRuns: params }
-      : { ...readConfigureGlobal(), ...params };
+      ? { ...(readConfigureGlobal() as Parameters<Ts>), numRuns: params }
+      : { ...(readConfigureGlobal() as Parameters<Ts>), ...params };
   const qParams: QualifiedParameters<Ts> = QualifiedParameters.read<Ts>(extendedParams);
   const recorded: { [key: string]: number } = {};
   for (const g of streamSample(generator, params)) {
diff --git a/src/check/runner/reporter/RunExecution.ts b/src/check/runner/reporter/RunExecution.ts
index f91f2786..f8ff66ff 100644
--- a/src/check/runner/reporter/RunExecution.ts
+++ b/src/check/runner/reporter/RunExecution.ts
@@ -92,13 +92,7 @@ export class RunExecution<Ts> {
     return [...offsetItems.slice(0, offsetItems.length - 1), `${middle}`, ...remainingItems.slice(1)].join(':');
   };
 
-  toRunDetails(
-    seed: number,
-    basePath: string,
-    numRuns: number,
-    maxSkips: number,
-    qParams: QualifiedParameters<Ts>
-  ): RunDetails<Ts> {
+  toRunDetails(seed: number, basePath: string, maxSkips: number, qParams: QualifiedParameters<Ts>): RunDetails<Ts> {
     if (!this.isSuccess()) {
       // encountered a property failure
       return {
diff --git a/tsconfig.json b/tsconfig.json
index e5ae74c3..20e530fa 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,22 +1,19 @@
 {
     "compilerOptions": {
-        "incremental": true,
         "declaration": true,
-        "sourceMap": true,
-        "alwaysStrict": true,
-        "noImplicitAny": true,
-        "noImplicitThis": true,
+        "importHelpers": false,
+        "incremental": true,
+        "noFallthroughCasesInSwitch": true,
         "noUnusedLocals": true,
-        "removeComments": false,
         "preserveConstEnums": true,
-        "strictNullChecks": true,
+        "removeComments": false,
+        "sourceMap": true,
+        "strict": true,
         "stripInternal": true,
-        "downlevelIteration": true,
-        "importHelpers": false,
+        "lib": ["es2017", "es2019.Symbol"],
         "module": "commonjs",
         "target": "es2017",
-        "lib": ["es2017", "es2019.Symbol"],
-        "outDir": "lib/"
+        "outDir": "lib/",
     },
     "include": [
         "src/**/*"


Test patch:
diff --git a/test/e2e/Shadows.spec.ts b/test/e2e/Shadows.spec.ts
index 048fc5ce..2efaa768 100644
--- a/test/e2e/Shadows.spec.ts
+++ b/test/e2e/Shadows.spec.ts
@@ -151,7 +151,7 @@ const SpaceArbitrary = fc
   .map(({ w, h, cx, cy, sx, sy }) =>
     new SpaceBuilder().withDimension(w, h).withSolution(cx, cy).withCurrent(sx, sy).build()
   )
-  .map((space: Space) => [space, Math.ceil(Math.log(Math.max(space.dimX, space.dimY)) / Math.log(2))]);
+  .map((space: Space): [Space, number] => [space, Math.ceil(Math.log(Math.max(space.dimX, space.dimY)) / Math.log(2))]);
 
 // Test
 
diff --git a/test/unit/check/arbitrary/SparseArrayArbitrary.itest.spec.ts b/test/unit/check/arbitrary/SparseArrayArbitrary.itest.spec.ts
index b6e80cf7..727f2adf 100644
--- a/test/unit/check/arbitrary/SparseArrayArbitrary.itest.spec.ts
+++ b/test/unit/check/arbitrary/SparseArrayArbitrary.itest.spec.ts
@@ -31,7 +31,7 @@ const validSparseArrayConstraints = () =>
 
 describe('SparseArrayArbitrary', () => {
   describe('sparseArray', () => {
-    genericHelper.isValidArbitrary((ct: SparseArrayConstraints) => sparseArray(nat(), ct), {
+    genericHelper.isValidArbitrary((ct: SparseArrayConstraints | undefined) => sparseArray(nat(), ct), {
       seedGenerator: fc.option(validSparseArrayConstraints(), { nil: undefined }),
       isEqual: (g1, g2) => {
         // WARNING: Very long loops in Jest when comparing two very large sparse arrays
diff --git a/test/unit/check/arbitrary/UuidArbitrary.itest.spec.ts b/test/unit/check/arbitrary/UuidArbitrary.itest.spec.ts
index a640eeec..64cfeeb3 100644
--- a/test/unit/check/arbitrary/UuidArbitrary.itest.spec.ts
+++ b/test/unit/check/arbitrary/UuidArbitrary.itest.spec.ts
@@ -11,7 +11,7 @@ describe('UuidArbitrary', () => {
   });
   describe('uuidV', () => {
     genericHelper.isValidArbitrary((constraint: 1 | 2 | 3 | 4 | 5) => uuidV(constraint), {
-      seedGenerator: fc.constantFrom(1, 2, 3, 4, 5),
+      seedGenerator: fc.constantFrom(...([1, 2, 3, 4, 5] as const)),
       isValidValue: (g: string, constraint: 1 | 2 | 3 | 4 | 5) =>
         /[0-9a-f]{8}-[0-9a-f]{4}-[12345][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/.test(g) &&
         g[14] === String(constraint),
diff --git a/test/unit/check/arbitrary/generic/GenericArbitraryHelper.ts b/test/unit/check/arbitrary/generic/GenericArbitraryHelper.ts
index 8ccdf7ae..c916d51b 100644
--- a/test/unit/check/arbitrary/generic/GenericArbitraryHelper.ts
+++ b/test/unit/check/arbitrary/generic/GenericArbitraryHelper.ts
@@ -145,19 +145,19 @@ export const isValidArbitrary = function <U, T>(
   },
   parameters?: fc.Parameters<unknown>
 ): void {
-  const seedGenerator = settings.seedGenerator || fc.constant(undefined);
+  const seedGenerator = settings.seedGenerator || fc.constant((undefined as unknown) as U);
 
   const biasedSeedGenerator = fc.tuple(fc.option(fc.integer(2, 100), { freq: 2 }), seedGenerator);
   const biasedArbitraryBuilder = ([biasedFactor, u]: [number | null, U]) => {
     return biasedFactor != null ? arbitraryBuilder(u).withBias(biasedFactor) : arbitraryBuilder(u);
   };
   const biasedIsValidValue = (g: T, [_biasedFactor, u]: [number | null, U]) => {
-    return settings.isValidValue(g, u);
+    return settings.isValidValue(g, u!);
   };
 
-  const assertEquality = (v1: T, v2: T, [, seed]: [number, U]) => {
+  const assertEquality = (v1: T, v2: T, [, seed]: [number | null, U]) => {
     if (settings.isEqual) {
-      if (!settings.isEqual(v1, v2, seed)) {
+      if (!settings.isEqual(v1, v2, seed!)) {
         throw new Error(`Expect: ${fc.stringify(v1)} to be equal to ${fc.stringify(v2)}`);
       }
     } else expect(v1).toStrictEqual(v2);
@@ -167,7 +167,7 @@ export const isValidArbitrary = function <U, T>(
   if (settings.isStrictlySmallerValue != null) {
     const isStrictlySmallerValue = settings.isStrictlySmallerValue;
     const biasedIsStrictlySmallerValue = (g1: T, g2: T, [_biasedFactor, u]: [number | null, U]) => {
-      return isStrictlySmallerValue(g1, g2, u);
+      return isStrictlySmallerValue(g1, g2, u!);
     };
     testShrinkPathStrictlyDecreasing(
       biasedSeedGenerator,
diff --git a/test/unit/check/runner/reporter/RunExecution.spec.ts b/test/unit/check/runner/reporter/RunExecution.spec.ts
index 60814a5a..00665648 100644
--- a/test/unit/check/runner/reporter/RunExecution.spec.ts
+++ b/test/unit/check/runner/reporter/RunExecution.spec.ts
@@ -30,7 +30,7 @@ describe('RunExecution', () => {
           }
           // Assert the value
           const lastFailure = failuresDesc[failuresDesc.length - 1];
-          const details = run.toRunDetails(seed, '', 42, 10000, QualifiedParameters.read({}));
+          const details = run.toRunDetails(seed, '', 10000, QualifiedParameters.read({}));
           expect(details.failed).toBe(true);
           expect(details.interrupted).toBe(false);
           expect(details.counterexamplePath).not.toBe(null);
@@ -64,7 +64,7 @@ describe('RunExecution', () => {
           run.fail(42, failureId, 'Failed');
         }
         // Assert the value
-        expect(run.toRunDetails(seed, '', 42, 10000, QualifiedParameters.read({})).counterexamplePath).toEqual(
+        expect(run.toRunDetails(seed, '', 10000, QualifiedParameters.read({})).counterexamplePath).toEqual(
           path.join(':')
         );
       })
@@ -89,7 +89,7 @@ describe('RunExecution', () => {
           joinedPath[offsetPath.length - 1] += addedPath[0];
           // Assert the value
           expect(
-            run.toRunDetails(seed, offsetPath.join(':'), 42, 10000, QualifiedParameters.read({})).counterexamplePath
+            run.toRunDetails(seed, offsetPath.join(':'), 10000, QualifiedParameters.read({})).counterexamplePath
           ).toEqual(joinedPath.join(':'));
         }
       )
@@ -123,13 +123,7 @@ describe('RunExecution', () => {
                 break;
             }
           }
-          const details = run.toRunDetails(
-            0,
-            '',
-            executionStatuses.length + 1,
-            executionStatuses.length + 1,
-            QualifiedParameters.read({})
-          );
+          const details = run.toRunDetails(0, '', executionStatuses.length + 1, QualifiedParameters.read({}));
           let currentExecutionTrees = details.executionSummary;
           for (let idx = 0, idxInTrees = 0; idx !== executionStatuses.length; ++idx, ++idxInTrees) {
             // Ordered like execution: same value and status