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

Encountered an issue while trying to run ionic serve - MODULE_NOT_FOUND

After cleaning my node modules and running ionic serve, I encountered the following error out of nowhere: Error: Module 'E:\xxxx\_work\10\s\xx\ff\dfd\node_modules\ionic' not found at Function.Mod ...

Error encountered when trying to release package to npm using semantic-release

While working on the release process in Circle CI using the semantic-release npm module, I encountered an error that states: [semantic-release] [@semantic-release/npm] › ℹ Write version 1.0.0 to package.json in /home/circleci/tmp npm ERR! Version not ...

JavaScript - Modifying several object properties within an array of objects

I am attempting to update the values of multiple objects within an array of objects. // Using a for..of loop with variable i to access the second array and retrieve values const AntraegeListe = new Array(); for (let i = 0; i < MESRForm.MitarbeiterL ...

Deleting a file from the assets folder in Angular for good

I am attempting to permanently delete a JSON file from the assets folder using my component. Despite trying to use HttpClient, I encounter no errors but the file remains undeleted. constructor(http: HttpClient){} remove() { this.http.delete('assets ...

"Unleashing the power of perpetual testing: A guide to seamlessly integrating Protractor with SauceL

My website has a web server running protractor tests, and I am looking to set up continuous testing with Saucelabs. According to Saucelabs, all I need to do is add my Saucelabs username and key to the conf.js file of Protractor. Would using cron or anothe ...

Typescript iterative declaration merging

My current project involves creating a redux-like library using TypeScript. Here is an example of the basic action structure: interface ActionBase { type: string; payload: any; } To customize actions for different types, I extend the base interface. ...

Upgrade the package to the latest major version using NPM

When working on a Node.js project, the process of upgrading a package to a major release may seem unclear at first glance. For example, let's say I want to install stylelint: npm install --save stylelint By default, this command adds "stylelin ...

Can someone guide me on the process of adding a personalized emoji to my discord bot?

After creating my own discord bot, I'm ready to take the next step and add custom emojis. While tutorials have helped me understand how to use client.cache to type an emoji, I'm unsure of how to upload them and obtain their ID for use in my bot. ...

Implementing unique union type in React: Effective ways to declare typescript type for prop value

I am currently facing an issue where I need to set a specific type for a prop value. However, the challenge lies in the fact that the types are string unions which can vary depending on the usage of the React Component. Let me provide you with the TypeScr ...

Error message: "The function RNFetchBlob.fetch is not a valid function in npm react-native-fetch-blob."

Currently, I am utilizing the npm package react-native-fetch-blob. I have meticulously followed all the steps provided in the git repository to implement this package. After following the instructions, I imported the package by using the following line ...

Introducing the 'node' type in tsconfig leads to errors in type definitions

I've encountered an issue with my NodeJS project where I have a type declaration file to add properties to the Request object: @types/express/index.d.ts: import { User } from "../../src/entity/user.entity"; declare global { namespace Exp ...

A step-by-step guide on leveraging ethereumjs-tx within a web browser

Is it necessary to install npm ethereumjs-tx when utilizing the browser-based version downloaded directly from GitHub? If so, how can we incorporate the ethereumjs-tx module into our script file? It seems like these are two separate components based on ...

Having trouble retrieving information from a JSON object? Unable to retrieve property 'company_about' of an undefined object?

Here is the JSON data I have: [ { "id": 1, "job_id": 1, "company_profile": "Sales and Marketing", "company_about": "Established in 1992 , it is a renouned marketing company", "company_product": "Ford,Mustang,Beetle", "key_skills": ...

Scraping data from a webpage using Node.js and the Document Object Model

I am attempting to extract information from a specific website using Node.js. Despite my best efforts, I have not made much progress in achieving this task. My goal is to retrieve a magnet URI link which is located within the following HTML structure: < ...

How to update the tsconfig.json file within a VS2019 project using MSBuild?

I am working with a Visual Studio solution that contains multiple tsconfig.json files and I would like them to have different behaviors in production. My plan is to create two additional files for this purpose: tsconfig.json will contain the default sett ...

The operation failed with a TypeError because the object does not allow the addition of the newField property

I encountered an error that says: TypeError: Cannot add property newField, object is not extensible Whenever I try to add a new key or change a value, it doesn't work and I'm not sure what the issue is. dynamicFilter; public ionViewWillEnte ...

A guide to creating a TypeScript redux middleware class

As specified in the typescript definition for Redux, these interfaces must be implemented to create middleware: /* middleware */ export interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> { dispatch: D getState(): S } /** * A midd ...

Personalize your Bulma experience using node-sass: resolving the npm init entry point dilemma

According to the documentation from Bulma (), it suggests running npm init and inputting sass/mystyles.scss as the entry point when prompted. However, I have come across information (What is "entry point" in npm init) suggesting that the entry po ...

What exactly does "context" refer to in the context of TypeScript and React when using getServerSideProps?

As a beginner in coding, I have a question regarding a specific syntax I recently encountered. I am confused about this particular line of code and couldn't find any helpful explanations online: export async function getServerSideProps(context: GetSer ...

Aggregate the data chunks in the antd table into groups

I've been struggling to find a solution for this specific issue. My goal is to group the data in my table based on a particular field, but I need it to be styled as depicted in the image linked below. https://i.stack.imgur.com/OsR7J.png After looking ...