Travis CI's TypeScript build process detects errors before Mocha has a chance to catch them

Instead of a bug, the TypeScript compiler is doing its job but causing my Travis builds to fail.

In my package, I have a function named completeRound which accepts a number as its first argument and 3 optional arguments. Since it's in TypeScript, I specify that it requires a number as the first argument:

function completeRound( number: number, rounding = 1, direction = 'closest', offset = 0 ): number {
  let n: number = +number,
      r: number = Math.abs(+rounding),
      d: string = direction,
      o: number = +offset;

  if (typeof n !== 'number') {
    throw new TypeError('You need to round a number!');
  }

  // Additional code here    
}

While everything operates fine, testing poses an issue. In my testing script:

import completeRound from '../src/completeRound';
import { expect } from 'chai';
import 'mocha';

const expectedResults = [
  {
    testVal : {
      number    : 3.5,
      rounding  : 1,
      direction : 'down'
    },
    eR      : 3
  },
  // Numerous other tests, all passing correctly
];

expectedResults.map(t => describe(`completeRound(${t.testVal.number}, ${t.testVal.rounding}, '${t.testVal.direction}', ${t.testVal.offset})`,() => {
  it(`should return ${t.eR}`, () => {
    const result = completeRound(t.testVal.number,t.testVal.rounding,t.testVal.direction,t.testVal.offset);
    expect(result).to.equal(t.eR);
  });
})); 

/* This line presents the problem */
expect(() => completeRound([5])).to.throw(TypeError, /a number/);
/* ---------------------------- */

expect(() => completeRound(5,1,'arriba')).to.throw(Error, /valid rounding direction/);

The challenge arises when I pass an array instead of a number, expecting JavaScript to trigger a TypeError. It's crucial for users utilizing either JavaScript or TypeScript to be equally covered. Furthermore, aiming for a flawless 100% coverage report. Nevertheless, the Travis report below reveals that the TypeScript compiler identifies the error first and throws a compilation error.

TSError: ⨯ Unable to compile TypeScript:

dev/test/completeRound.spec.ts:414:28 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'number'.

414 expect(() => completeRound([5])).to.throw(TypeError, /a number/);

I'm unable to test the compiled code directly, as it necessitates compiling it through webpack, storing it in the ./dist directory, and bundling it, complicating the process. Importing from this output seems impractical, and having a two-step process involving compiling then bundling isn't ideal.

In essence, I seek to ascertain JavaScript's ability to catch errors that TypeScript would detect automatically but JavaScript wouldn't. Any assistance would be greatly appreciated.

Answer №1

After reviewing the code, I noticed a couple of issues:

  1. One problem is in the function completeRound(). You are using unary plus (n = +number), which always converts the value to a number. It would be better to first check if the input is a valid number before proceeding. You can achieve this by either checking the type of the parameter or using isNaN() method as shown below:
function completeRound(number: number): number|TypeError {
  // Check if input is a number.
  if (typeof number !== 'number') {
    throw new TypeError('You need to round a number!');
  }
  
  const n: number = +number;
  // Check if n is NaN.
  if (Number.isNaN(n)) {
    throw new TypeError('You need to round a number!');
  }
  
  // Continue with the rest of the code here
  return n;
}
  1. Another suggestion is to use unknown type and perform type assertion. Here's an example:
// Declare testVar as unknown.
const testVar:unknown = [5];
// Perform type assertion on testVar.
expect(() => completeRound(testVar as number)).to.throw(TypeError, /a number/);

// Attempt with a function.
const testVarAgain: unknown = () => false;
expect(() => completeRound(testVarAgain as number)).to.throw(TypeError, /a number/);

I hope this clarifies things for you. Best of luck!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display a modal dialog using HttpInterceptor

@Injectable() export class MyInterceptor implements HttpInterceptor { intercept(req : HttpRequest<any>, next : HttpHandler) : Observable<HttpEvent<any>> { //display a modal dialog to wait for user response before proceeding with t ...

Deactivating PrimeNG checkbox

I am currently facing an issue with disabling a PrimeNG checkbox under certain conditions by setting the disabled property to true. However, whenever I click on the disabled checkbox, it refreshes the page and redirects me to the rootpage /#. To troublesh ...

Why did my attempt to run "npm install --only=prod @hyperledger/[email protected]" fail?

My current challenge involves installing Caliper from NPM using version 7.19.1, with guidance from the documentation at Upon executing the command: npm install --only=prod @hyperledger/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfe ...

Distribution running of VueJS doesn't show styles

Even though I am able to successfully run my Vuejs app using nom run serve, I am facing an issue when I build it and deploy it to nginx. None of my styles, especially bootstrap, are appearing. Despite my app logic appearing correct and all my js and css ...

The file functions/lib/functions/src/index.ts is missing, preventing the deployment of Cloud Functions

Whenever I attempt to deploy my Firebase cloud functions, I encounter the following error. Expected outcome: Successful deployment of functions. Error: Error: An issue occurred while reading functions/package.json: functions/lib/index.js is missing and ...

Encountering unexpected errors with Typescript while trying to implement a simple @click event in Nuxt 3 projects

Encountering an error when utilizing @click in Nuxt3 with Typescript Issue: Type '($event: any) => void' is not compatible with type 'MouseEvent'.ts(2322) __VLS_types.ts(107, 56): The expected type is specified in the property ' ...

Update and republish an outdated npm package

After successfully publishing an npm package, I attempted to make an update which unfortunately resulted in some issues. It seems that I made a mistake during the build process. Since it had been a year since my last update, I have forgotten the exact step ...

Function with a TypeScript Union Type

I'm attempting to define a property that can be either a lambda function or a string in TypeScript. class TestClass { name: string | () => string; } You can find a sample of non-working code on the TS playground here. However, when compiling ...

Angular Nested Interface is a concept that involves defining an

Looking for guidance on creating a nested interface for JSON data like this: Any help is appreciated. JSON Structure "toto": { "toto1": [], "toto2": [], "toto3": [], } Interface Definition export interface Itot ...

The module 'balanced-match' was not found by NPM

I keep encountering an issue whenever I attempt to run a command with npm: module.js:340 throw err; ^ Error: Cannot find module 'balanced-match' at Function.Module._resolveFilename (module.js:338:15) at Function.Module._loa ...

Using TypeScript's conditional types for assigning types in React

I'm tasked with creating a component that can belong to two different types. Let's call them Type A = { a: SomeCustomType } Type B = { b: SomeOtherDifferentType } Based on my understanding, I can define the type of this component as function C ...

Different Port Options for an Alternative to npm's http-server

In our various projects, we utilize http-server and Express to serve different components on different ports. For example, the user interface may be on port 8080, while some API endpoints are on port 4040. However, as I frequently have multiple projects r ...

What is the process for testing an iframe and retrieving all of the response headers?

I'm currently working on a web application that can display URLs in an iframe. However, I also want to be able to test the URL before showing it in the iframe. The goal is to wait for a response and only display the iframe if there are no errors or if ...

What is the best way to access the data being sent to a router link in Angular?

After navigating to the user page using the router sample below, how can I retrieve the details once it reaches the user page? I need to verify in my user.component.ts that the navigation is triggered by this [routerLink]="['user', user.id, &apo ...

Access the configuration file within the "scripts" section of the package.json file

Is there a way to configure a custom port for the "serve" script in package.json by reading from a config file? Context: Our team of developers is working on the same terminal server. In our package.json file, we have the following section: ... "scripts" ...

Why are these additional curly brackets added within an else statement?

Upon reviewing some typescript code, I noticed the presence of extra curly braces within an else block. Are these additional braces serving a specific purpose or are they simply used to provide further grouping for two nearly identical code snippets? Consi ...

Version 4.0 of Electron-React-Boilerplate has encountered an error: The property 'electron' is not recognized on the type 'Window & typeof globalThis'. Perhaps you meant to use 'Electron' instead?

I encountered an error while attempting to call the IPCrenderer using the built-in context bridge. The error message reads as follows: Property 'electron' does not exist on type 'Window & typeof globalThis'. Did you mean 'Elect ...

Ways to access the chosen value from Ionic's popover modal

I have been working on a simple Ionic 4 Angular app and I am using an Ionic popover modal. The code below shows how I open the popover modal in my application: //home.page.ts async openModal(ev: Event) { const modal = await this.popoverController.create({ ...

Innovative solution for detecting and replacing undefined object properties in Angular 2 with TypeScript

After encountering the issue of core.umd.js:3523 ORIGINAL EXCEPTION: Cannot read property 'fullName' of undefined I realized that the Exception stemmed from a Template trying to access a specific property: {{project.collaborators["0"]["fullN ...

Error message: `npm installation failed to read the package.json file

I need help managing my node package dependencies. I want to be able to easily install all the necessary dependencies with a simple command. After some research, it seems like using a `package.json` file and running `npm install` is the way to go. Here&apo ...