What is the process for including a custom Jasmine matcher definition in Typescript?

I've been searching around for information on creating custom Jasmine matchers using TypeScript and it seems like a common issue. However, none of the solutions I've come across have worked for me.

My setup includes:

{
  "typescript": "2.3.2",
  "jasmine-core": "2.6.1",
  "@types/jasmine": "2.5.47"
}

I am struggling to get Typescript to merge the namespace declaration that contains my custom matcher definition.

When adding the following code snippet:

declare namespace jasmine {
  interface Matchers<T> {
    toBeAnyOf(expected: jasmine.Expected<T>, expectationFailOutput?: any): boolean;
  }
}

This causes other types previously declared in the jasmine namespace to be hidden. Compiler errors are thrown such as:

[ts] Namespace 'jasmine' has no exported member 'CustomMatcherFactories'
[ts] Namespace 'jasmine' has no exported member 'CustomMatcher'.

Is there a proper way to add a custom matcher and ensure compatibility with Typescript?

Another complication arises when using the tslint:recommended ruleset which disallows the usage of keywords like namespace or module. As a result, I had to disable the linter or modify the rule in order to proceed. It's unclear how one might extend definitions if this approach is considered "not recommended".

Answer №1

When incorporating custom matchers, I had to adjust three separate files. First, I created a file named matchers.ts which housed the actual matchers themselves. Next, I included an import for my matchers.ts file in test.ts. Lastly, I updated the typings.d.ts file by adding an interface that contains my matcher.

matchers.ts (placeholder name)

beforeEach(() => {
    jasmine.addMatchers({
        toContainText: () => {
            return {
                compare: (actual: HTMLElement, expectedText: string, customMessage?: string) => {
                    const actualText = actual.textContent;
                    return {
                        pass: actualText.indexOf(expectedText) > -1,
                        get message() {
                            let failureMessage = 'Expected ' + actualText + ' to contain ' + expectedText;

                            if (customMessage) {
                                failureMessage = ' ' + customMessage;
                            }

                            return failureMessage;
                        }
                    };
                }
            };
        },
    });
});

test.ts

import 'test/test-helpers/global/matchers'; (my relative filepath)

typings.d.ts

declare module jasmine {
  interface Matchers {
    toContainText(text: string, message?: string): boolean;
  }
}

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

Express npm dependency fails to start globally

I have recently reinstalled my operating system from Windows 8.1 to Windows 8.1, and I have been using npm for quite some time. Previously, it was working fine as mentioned here. After the reinstallation, I tried installing npm i -g express, but it does n ...

Using jQuery Ajax to Send Values Between Functions and Replace Nulls

I need assistance with handling the value from a dropdownlist in my JavaScript function. The function works well if the value is not Null, but I want to replace a Null value with the static value "asc" before passing it to the next function. function g ...

The attribute 'title' is not found in the data type 'Projects[]'

When attempting to retrieve data from a specific link, I encounter error TS2339: Property 'title' does not exist on type 'Projects[]', despite the presence of the 'title' property in 'Projects'. The goal is to access ...

Turn off ion-slide when the application starts

Is there a way to prevent the slide feature from activating upon startup while still allowing me to set my own active page? I've discovered this helpful snippet in HTML <ion-slide-box active-page="disableSlide()"> <ion-slide>Slide 1& ...

When the Next js page loads, it briefly displays a 0 at the top for a moment before loading the rest

When my nextjs app loads a page, there is a momentary appearance of a 0 in the top left corner. This happens even if I am fetching data from Sanity CMS using getStaticProps and returning content. Interestingly, I have observed that simply returning an empt ...

How to Enhance Angular ui-router nested views with Resolve?

I have been working on creating a customized version of my Angular 1.4.12 application with nested views. The main purpose behind this customization is to accommodate sections within the app that require a header/content/footer structure, while others do no ...

When utilizing the dojox.grid.enhanceGrid function to delete a row, the deletion will be reflected on the server side but

I have a grid called unitsGrid that is functioning correctly. I am able to add and delete rows, but the issue arises when I try to delete rows - they do not disappear from my unitsGrid. I have spent hours trying to debug the code but I cannot seem to fin ...

Tips for including an additional label on a data point within a scatter plot using the Highcharts JavaScript framework

Incorporating the Highcharts JavaScript library, I am visualizing float values by passing them from PHP to the JS code. In the image below, you can observe that upon hovering over each point, the corresponding axes values are displayed along with the text ...

Tips for showing a single table with buttons on display

I am using R markdown and have included multiple tables with buttons, but when I open the file, all tables are displayed at once. How can I ensure only one table is shown upon opening the file? <script type="text/javascript"> function sh ...

Navigating through a large number of distinct items in Three.JS

I have hit a roadblock in my project development. I am striving to create a level using various phong materials on objects of unique sizes and shapes. However, Three.JS's default texture handling causes them to stretch out and look distorted on meshes ...

Having trouble getting two components to return in React

After successfully implementing the Hello World example by returning "Hello" and "world" from two different components, I encountered a problem with my code. In this specific code snippet, I am unable to return the Menubar component, although the Map compo ...

Booting up a module in AngularJS without using automatic bootstrapping

Here is the structure of my HTML... <body id="main"> {{pageName}} </body> This is how I implement it in JavaScript: angular.module('myApp',[]) .controller('myController', function($scope){ console.log('initial ...

Experiencing issues when deploying an Angular application on Heroku and when trying to run ng serve?

Encountering the error message "The serve command requires to be run in an Angular project, but a project definition could not be found." Here is the content of my package.json file. { "name": "demo-deploy", "version": "0.0.0", "license": "MIT", "scripts ...

What are the benefits of using Lifery Ajax URLs?

I'm currently using the Grails portlets plugin and I'm exploring how to properly route AJAX methods. It seems like <portlet:actionURL> is only able to map to methods that return models for GSPs, while <portlet:resourceURL> doesn&apos ...

I have a desire to use Javascript to control CSS styles

Within the CSS code below, I am seeking to vary the size of a square randomly. This can be achieved using the Math.random() property in Javascript, but I am uncertain how to apply it to define the size in CSS. #square { width: 100px; height: ...

Sending file URL to Angular component

Hey there, I am looking to relocate an existing link within my Angular 4 project. For instance, the link I want to move is "". I have attempted to do so in my router configurations: path: 'test', component: TestComponent, children: ...

Using JavaScript, extract the most recent 10 minutes worth of UNIX timestamps from a lengthy array

I am working with an array that contains multiple UNIX timestamps and I need to retrieve the timestamps from the last 10 minutes. Specifically, I only require the count of these timestamps, possibly for a Bot protection system. Would it be best to use ...

What is the method for retrieving the index of an array from an HTML element?

Howdy! Within my Vue application, I have the ability to create multiple individuals: <div v-for="newContent in temp" :key="newContent.id" @click="showId(newContent.id)" v-show="true"> <!-- ...

What is the process for setting environment variables in a Svelte project?

I'm brand new to working with Svelte and I want to incorporate environment variables like base_url into different components. I've read that I can set up a store to hold these values, for example: const DataStore = writable([ { base_url: & ...

When a user reverts UI changes to their original values in Angular reactive forms, does the pristine state reset?

I need the Submit button in my form to only be enabled when there is a change in the input. If the values in the form controls remain unchanged, the Submit button should be disabled. Initially, I attempted to utilize the FormGroup.pristine flag for toggl ...