Is there a way to achieve this using a fresh and sleek typescript assertion function?

Presented below is the snippet of code:

type Bot = BotActive | BotInactive;

class BotActive {
    public readonly status = "active";

    public interact() {
        console.log("Hello there!");
    }
}

class BotInactive {
    public readonly status = "inactive";
}

function canInteract(bot: Bot) {
    if (bot.status === "inactive") throw Error("Bot cannot interact when it's inactive!");

    bot.interact();
}

Now, I am interested in verifying the status of the bot using a TypeScript assertion function! Here's what I have in mind:

function canInteract(bot: Bot) {
    assertBotStatus(bot, "active");

    bot.interact();
}

Is there a way to achieve this? If so, how would the assertBotStatus function be implemented?

Your help is greatly appreciated!

Answer №1

One way to validate the type of an argument is by using assertion statements -

asserts <<arg>> is <<type>>
.

function assertRobotStateOn(robot: Robot): asserts robot is RobotOn {
  if (robot.state !== 'on') {
    throw new Error('Robot is Off!');
  }
}
function assertRobotStateOff(robot: Robot): asserts robot is RobotOff {
   if (robot.state !== 'off') {
    throw new Error('Robot is On!');
  }
}
function maybeSpeak(robot: Robot) {
    assertRobotStateOn(robot);

    robot.speak();
}
maybeSpeak(new RobotOff());

For more information, you can refer to:

Answer №2

Success! I've discovered a solution using overloaded assertion functions! Check out the code snippet below:

type Android = Active | Inactive;

class Active {
    public readonly status = "active";

    public greet() {
        console.log("Hello there!");
    }
}

class Inactive {
    public readonly status = "inactive"
}

function maybeGreet(android: Android) {
    assertAndroidStatus(android, "active");

    android.greet();
}

function assertAndroidStatus(robot: Android, status: "active"): asserts robot is Active;
function assertAndroidStatus(robot: Android, status: "inactive"): asserts robot is Inactive;
function assertAndroidStatus(robot: Android, state: "active" | "inactive") {
    if (robot.status !== state) throw new Error("Error: Invalid status");
}

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

Can you explain the purpose of the curly braces found in a function's parameter definition?

I am currently working on an Angular 5 project and came across this intriguing Typescript code snippet. (method) CreateFlightComponent.handleSave({ currentValue, stepIndex }: { currentValue: Partial<Flight>; stepIndex: number; }): void Can ...

Setting button height dynamically in React Native

I've implemented a button using React Native Elements in my layout. Here's the code snippet: <Button title="Login" buttonStyle={{ backgroundColor: Colour.green }} containerStyle={{ ...

The value of Angular Input remains unchanged within a FormArray

I am experiencing an issue with the Sequence No in my PreprocessingForm's FormArray. When I add a new row, the Sequence No does not change as expected. <tr class="mat-row" *ngFor="let dynamic of PreprocessingForm.controls.arithmeticI ...

Can type information be incorporated during compilation?

Consider the code snippet below: function addProperties(keys: String[]): Object { // For illustration purposes, this is a specific return return { firstProperty: "first_value", secondProperty: "second_value" }; } export defaul ...

Using Typescript in React to render font colors with specific styling

Attempting to utilize a variable to set the font color within a react component, encountering an error with my <span>: Type '{ style: "color:yellow"; }' is not assignable to type 'HTMLProps<HTMLSpanElement>' The use of yel ...

Having trouble with Angular 2's Output/emit() function not functioning properly

Struggling to understand why I am unable to send or receive some data. The toggleNavigation() function is triggering, but unsure if the .emit() method is actually functioning as intended. My end goal is to collapse and expand the navigation menu, but for ...

What steps can I take to fix the 'node module error' while deploying a project on Vercel?

While working with the world-countries package, I encountered an issue during deployment in Vercel. The error message indicated that a ';' was missing in the index.d.ts file of world-countries located in the node_module directory. Here is the ex ...

Exploring the Method of Utilizing JSON Attribute in typeScript

How to access JSON attributes in TypeScript while working on an Angular Project? I'm currently in the process of building an Angular project and I need to know how to access JSON attributes within TypeScript. test:string; response:any; w ...

You won't find the property 'includes' on a type of 'string[]' even if you're using ES7 features

I encountered a similar issue on another page where it was suggested to modify the lib in tsconfig.josn. However, even after changing compile to es7, the same error kept appearing and the project couldn't be compiled or built. { "compileOnSave": ...

Internet Explorer is throwing unexpected routing errors in Angular 2

I have a spring-boot/angular 2 application that is working perfectly fine on Chrome, Safari, Opera, and Edge. However, when accessed through Internet Explorer, the app directly routes to the PageNotFound component. I have tried adding shims for IE in the i ...

Testing the MatDialog Component

Currently, I am in the process of creating a unit test for my confirmation modal that relies on MatDialog. The initial test I have set up is a simple one to ensure that the component is successfully created. Below is the code snippet from my spec file: im ...

What is the process for importing libraries from a different local directory?

What I mean by that title is: I have some code that was generated and now I am incorporating it into my Angular application. Currently, I am installing this code as a package using npm, but it is causing issues with my deployment setup. So, I would like ...

When using the .concat method on an array, props may display as unidentified

When I log the items array in my props, it contains items. However, when I try to add to the array using .concat, I encounter an error stating Cannot read property 'concat' of undefined export default (props) => { const { items } = props; ...

An error of type TypeError has been encountered due to an invalid argument type. This occurred in the file located at {mypath}Desktop eddit ode_modules@redisclientdistlibclientRESP2encoder.js on line

Currently, I am diving into Ben's TypeScript GraphQL Redis tutorial for the first time. As a newcomer to TypeScript, I decided to give Redis a shot. However, when I added the property req.session.userId= user.id;, things took a turn. An error popped ...

`What exactly do auth.guard.ts and the AuthenticationService do in Angular 8?`

import { Injectable } from '@angular/core'; import { AuthenticationService } from './_services'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; @Injectable({ providedIn: & ...

Explain the object type that is returned when a function accepts either an array of object keys or an object filled with string values

I've written a function called getParameters that can take either an array of parameter names or an object as input. The purpose of this function is to fetch parameter values based on the provided parameter names and return them in a key-value object ...

Error: Trying to modify an immutable property 'title' of object '#<Object>' - React JS and Typescript

Whenever I press the Add button, all input values are stored in a reducer. However, if I append any character to the existing value in the input fields, it triggers the following error: Cannot assign to read only property 'title' of object &apos ...

Issue: Module 'stylelint' not found in Angular Project

I've been attempting to execute this command to validate all of the .scss files (and even tried with .css files) and I keep encountering this error. $ stylelint "apps/**/*.scss" It worked once before but not anymore, even after restarting my compute ...

Why doesn't Typescript 5.0.3 throw an error for incompatible generic parameters in these types?

------------- Prompt and background (Not crucial for understanding the question)---------------- In my TypeScript application, I work with objects that have references to other objects. These references can be either filled or empty, as illustrated below: ...

Typescript: Utilizing method overloading techniques

I'm in the process of implementing function overloads that look like this: public groupBy(e: Expression<any>): T { e = this.convert(e, Role.GROUP_BY); this.metadata.addGroupBy(e); return this.self; } public grou ...