Testing TypeScript data types through unit tests

In one of my modules, I have the following export:

export class Action1 implements Action {}

export class Action2 implements Action {}

export type ActionsUnion =
  | Action1
  | Action2;

I'm currently exploring the best approach to testing ActionsUnion and ensuring it aligns with the defined types. For instance:

it('should have the correct types', () => {
  expect(typeof Action1).toEqual(ActionsUnion);
  expect(typeof Action2).toEqual(ActionsUnion);
});

Obviously, the above code doesn't work since I'm using ActionsUnion as a variable. Any suggestions on how to accomplish this?

Just for context, I am working with angular, ngrx, and jasmine.

Answer №1

tsafe allows for the unit testing of types, as demonstrated below:

// The following test file is not meant to be executed; it passes only if there are no TypeScript errors.

import { assert, Equals } from "tsafe";

declare function myFunction<T extends string>(arr: T[]): T;

{

  const got = myFunction([ "a", "b", "c" ]);

  type Got = typeof got;

  type Expect = "a" | "b";

  // A TS error is present here, as expected
  // In this case:
  // Got is        "a" | "b" | "c"
  // and Expect is "a" | "b"
  assert<Equals<Got, Expect>>();

}

{

  const got = myFunction([ "a", "b", "c" ]);

  type Got = typeof got;

  type Expect = "a" | "b" | "c";

  // ✅ Got and Expect should be the same type
  assert<Equals<Got, Expect>>();

}

{

  //@ts-expect-error: Passing numbers should not be allowed
  myFunction([ "a", 42, "c" ]);

}

{

    // This section shows an error expecting expression validity
    //@ts-expect-error
    myFunction([ "a", "b", "c" ]);

}

{

  const got = myFunction([ "a", "b", "c" ]);

  type Got = typeof got;


  // Validation to ensure that Got is a string type
  assert<Got extends string ? true : false>();


}

{

  type T = "a" | "b";
  type U = string;

  // Verifying that T extends U
  assert<T extends U ? true : false>();

}

In this code snippet example:

import { assert } from "tsafe/assert";
import type { Extends } from "tsafe";

type Action= { _signature: undefined; }

 class Action1 implements Action {
   _signature: undefined;
 }

 class Action2 implements Action {
  _signature: undefined;
 }

export type ActionsUnion =
  | Action1
  | Action2;

assert<Extends<Action1, ActionsUnion>>();

Full credit goes to the author of this content.

Answer №2

I have yet to experiment with using a union in this context, but you could explore the possibility of using jasmine.any(Type). If implemented, your code snippet would look like this:

it('should validate the correct types', () => {
  expect(Action1).toEqual(jasmine.any(ActionsUnion));
  expect(Action2).toEqual(jasmine.any(ActionsUnion));
});

For further information, check out:

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

Angular 8: Efficiently Applying Filters to JSON Data Stored in LocalStorage

In my Angular 8 project, I am storing data in localStorage and need to filter it. However, I am unsure about the method to use. Here is how the localStorage values look: [{id: 9, designation: "spectacle + restaurant", gift: [], type: "Soirée Bon plan", ...

Is Drizzle ORM able to handle decimal values in MySQL as strings?

The data structure: export const myTable = mysqlTable( "MyTable", { id: varchar("id", { length: 191 }).notNull(), value: decimal("value", { precision: 7, scale: 4 }).notNull(), createdAt: datetime("created ...

What is the best way to retrieve the Parent component's name within a Child component in Angular 2?

In my scenario, I have three elements: C1, C2, and C3. I need to designate C2 as both a child of C1 and C3. Based on which element is the parent of C2, I want to display the HTML text - "C1 is my parent" or "C3 is my parent". This summarizes the issue at ...

Leveraging i18next to substitute a variable with a ReactNode component

My translation json file contains the following translation: "pageNotFound": { "description": "The page could not be found. Click {{link}} to return to the home page" }, I am looking to replace the link variable with a ReactRouter <Link> Within ...

Angular failing to retrieve URL parameters correctly

As I was trying to retrieve URL queries like www.website.com?a:b, I decided to follow the guidance provided in a particular Angular tutorial. This official tutorial (accessible via this link) instructed me to implement the following simple code snippet wit ...

Retrieving a result from the reduce function in Angular

Is there a way to use the reduce function in order to return a list of objects? I am currently only able to return a single object with keys as project names and values as hours: { Name1: 9, Name2: 10, Name3: 30, } What changes can I make to my code to ac ...

Collection of personalized forms where the parent is a FormGroup

One scenario I'm working on involves creating multiple custom formgroup classes that have FormGroup as their parent class, structured like this: export class CustomFormGroup1 extends FormGroup { //custom properties for this FormGroup const ...

I am having trouble getting my angular library published successfully

I'm facing an issue while trying to publish my angular package. I keep encountering this error. https://i.stack.imgur.com/nhYMY.png Here is a screenshot of my package.json file https://i.stack.imgur.com/mWsin.png. ...

Initiate the script once ng serve is running

Recently, I created a script to capture screenshots of my Angular application. However, I encountered an issue where the script only functions correctly if I manually start 'ng serve' before running the script. My concern is, is there a way to in ...

Setting the response type to text in Angular 6 when making an http call

Attempting to send an HTTP request to the Spring REST API, which returns a string value ('success' or 'fail'). However, I am uncertain of how to specify the response type as a string value when making the call to the API. The error mess ...

What are some ways to leverage a promise-returning callback function?

Here is a function that I have: export const paramsFactory = (params: paramsType) => { return ... } In a different component, the same function also contains await getPageInfo({ page: 1 }) after the return .... To make this work, I need to pass a cal ...

What benefits could be gained from enabling the compiler option "declaration" in a TypeScript project?

I am currently working on a TypeScript project and contemplating the possibility of publishing it as an NPM package in the future. Currently, I have the "declaration": true setting in my tsconfig.json, which is causing some issues that are irrelevant to t ...

Utilizing Typescript to Transfer Data from Child to Parent in React

Attempting to pass data from a Child Component to a Parent component using Typescript can be challenging. While there are numerous resources available, not all of them delve into the TypeScript aspect. One question that arises is how the ProductType event ...

The cdkDropListSortingDisabled attribute is not recognized as a valid property for the cdkDropList directive in Angular Material

I'm trying to achieve a specific use case where I need to drag and drop data from one zone (div) to another. After some research, I discovered that angular/material2 with the cdkDropList API could help me accomplish this task. Using the copyArrayitem ...

TypeScript: Unable to retrieve values or keys from a Map data structure

Issue arises when attempting to access map keys or values using a method, resulting in the following error: ERROR TypeError: factors.values is not a function or its return value is not iterable These model interfaces are used for object types: export ...

Resolve functionality in UI Router fails to function properly when utilizing component-based states

Issue: In a project I am currently involved in, there is a component that is utilized in two different scenarios. One instance involves calling it from the Material Design system's bottomSheet, while the other requires direct usage through the ui-ro ...

The billing cycle on the Stripe invoice does not match up

I'm currently in the process of integrating Stripe into my SaaS platform, and I've encountered an issue with calculating the quota based on the payment period. Despite setting the plan as monthly, Stripe is returning a period from the 70s through ...

Here is a guide on sorting through data within an array of objects using React.js and Typescript

How can I filter dealers' data based on the minimum and maximum price range of a slider change? I am retrieving dealers' data using an API and storing the slider's min and max values in a handle change function. What is the best way to filte ...

What is the process of molding items?

Here is an object that I have: { "id": "Test", "firstname": "Test", "lastname": "Test", "age": 83 } However, I only want to return the object with this value: { "id&quo ...

How can Node / Javascript import various modules depending on the intended platform?

Is there a way to specify which modules my app should import based on the target platform in TypeScript? I am interested in importing different implementations of the same interface for a browser and for Node.js. In C++, we have something like: #ifdef wi ...