Currently attempting to ensure the type safety of my bespoke event system within UnityTiny

Currently, I am developing an event system within Unity Tiny as the built-in framework's functionality is quite limited. While I have managed to get it up and running, I now aim to enhance its user-friendliness for my team members. In this endeavor, I attempted to employ typeguarding to restrict users from utilizing different types, but unfortunately, I encountered difficulties in making it work effectively. Do you have any suggestions or insights that could help me overcome this challenge?

I have already explored the following resources: - https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0 - https://dev.to/krumpet/generic-type-guard-in-typescript-258l

One key challenge I faced is that Unity Tiny utilizes ES5, which restricts access to object.constructor.name for determining the type name. Consequently, leveraging "instanceof" proves to be unfeasible.

Furthermore, attempts such as (object as T) or (object as T).type have not yielded successful outcomes for me.

export class Event<T> implements IEvent<T>{
        private handlers: {(data?: T): void}[] = [];
        public type : T;

        constructor(value: T){
            this.type = value;
        }


        public On(handler: { (data?: T): void }) : void {
            this.handlers.push(handler);
        }

        public Off(handler: { (data?: T): void }) : void {
            this.handlers = this.handlers.filter(h => h !== handler);
        }

        public Trigger(data?: T) {
            this.handlers.slice(0).forEach(h => h(data));
        }

        public Expose() : IEvent<T> {
            return this;
        }
    }
export class EventUtils {
        public static events = new Object();

        public static CreateEvent<T>(eventEntity: ut.Entity, nameOfEvent: string) : void{
            this.events[nameOfEvent] = new game.Event<T>();
        }

        public static Subscribe<T>(nameOfEvent: string, handeler: {(data? : T): void}) : void{
            //Loop through events object, look for nameOfEvent, use checkEventType() to check if it is the same type as given generic, then subscribe if true.
        }

        public static Trigger<T>(nameOfEvent: string, parameter?: T) : void{
            //Loop through events object, look for nameOfEvent, use checkEventType() to check if it is the same type as given generic, then trigger if true.
        }

        private static checkEventType<T>(object: any) : object is Event<T>{
            let temp : T;
            let temp2 = {temp};

            if (object.type instanceof temp2.constructor.name) {
                return true;
            }
            return false;
        }
    }
}
private static checkEventType<T>(object: any) : object is Event<T>{
            let temp : T;

            if (object.type as typeof temp) {
                return true;
                //always returns true even if the type is different
            }
            return false;
        }
    }

Additionally, I encountered issues with:

let temp : T;

            if ((object.type as typeof temp).type) {
                return true;
                //property 'type' does not exist in 'T'  
            }
            return false;

Answer №1

instanceof has been around for a while and is supported, making it usable even in ES5.

The issue lies in the way you are conducting your check. To verify an instance of a class, you must actually have the class (not just the type) within the checkEventType function:

public static checkEventType<T>(cls: new (...a: any[]) => T, object: any): object is Event<T> {
    if (object.type instanceof cls) {
        return true;
    }
    return false;
}

Play

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

Struggling to map the response data received from an http Get request to a TypeScript object that follows a similar structure

Currently, I am invoking an http Get service method from a component to retrieve data and map it to a Person object. The goal is to display this information on the front end. Below is my component code: export class DisplayPersonComponent implements OnIni ...

Specializing Generic Types in Typescript

I'm interested in exploring specialization within Typescript generics, allowing for implementations to vary based on specific type criteria. Here's a simple illustration: const someFunction = <A>() => { return 0; } // something simila ...

Injecting a useFactory provider in Angular is a common practice

I manage a factory provider service that selects a service based on a flag. Everything works fine when I need a debug students service, but when I set the flag to false, the application throws an ERROR TypeError: serverService.fetchData is not a function. ...

Modifying the date format of the ag-Grid date filter

On my Angular 5.2.11 application, I utilize ag-grid to showcase a table. The date column is configured with the default date filter agDateColumnFilter as per the documentation. After enabling browserDatePicker: true, the Datepicker displays dates in the ...

I am looking to conceal the y-axis labels and tooltip within the react chart

I am currently working with react-chart-2. I have a line graph that displays a tooltip when hovered over, but I would like to hide this tooltip feature. Additionally, I want to remove the numbers 0, 0.1, 0.2 up to 1 on the left side (y-axis) of the gra ...

A guide on transitioning from using require imports to implementing ES6 imports with the concept of currying

Currently in the process of migrating a Node/Express server to TypeScript. I have been using currying to minimize import statements, but now want to switch to ES6 import syntax. How can I translate these imports to ES6? const app = require("express")(); ...

Developing a dynamic web application using Asp.Net Core integrated with React and material

After setting up an Asp.Net Core project using the react template, I decided to incorporate material-ui by following the steps outlined on this page. However, encountered some dependency issues along the way. To resolve them, I had to update the react and ...

Having trouble getting Angular 8 WebRTC to function properly on two tabs

I've been tasked with creating an audio chat room for 2 users. Initially, I used the following app example: Peer connection: audio only After converting the code to TypeScript, it successfully ran: Stackblitz However, I'm facing challenges ge ...

The specified type '{ children: Element; ref: MutableRefObject<HTMLDivElement>; }' cannot be matched with type 'IntrinsicAttributes & RefAttributes<HTMLDivElement>' in the assignment

Encountering an issue with fowardRef in ReactJS where everything seems fine, but an error pops up: Type '{ children: Element; ref: MutableRefObject<HTMLDivElement>; }' is not assignable to type 'IntrinsicAttributes & SectionContent ...

Retrieve all services within a Fargate Cluster using AWS CDK

Is there a way to retrieve all Services using the Cluster construct in AWS CDK (example in TypeScript but any language)? Here is an example: import { Cluster, FargateService } from '@aws-cdk/aws-ecs'; private updateClusterServices(cluster: Clus ...

I'm curious about how to link a JSON field using dot notation in Angular 12 HTML

Does anyone know how to bind a JSON field using dot paths in Angular 12 HTML? For example: //Angular data: any = { name: 'x1', address: { city: 'xyz' } }; field: any = 'address.city'; //Html <input [(ngModel)]="data[ ...

Tips for troubleshooting TypeScript integration tests within Pycharm

Currently, I have been utilizing PyCharm to code in typescript. To run tests in the integration directory, I execute npm run test:integration. However, I am now looking to debug the tests. The directory structure looks like this: my_project /src /tests ...

How can we prevent new chips (primeng) from being added, but still allow them to be deleted in Angular 2?

Hey there! I'm currently exploring how to make the chips input non-editable. I am fetching data objects from one component and using the keys of those objects as labels for the chips. Check out my HTML code below: <div class="inputDiv" *ngFor="le ...

Can you explain the distinction between declaring type using the colon versus the as syntax?

Can you explain the variation between using the : syntax for declaring type let serverMessage: UServerMessage = message; and the as syntax? let serverMessage = message as UServerMessage; It appears that they yield identical outcomes in this particular ...

Can discriminated unions solely be utilized with literal types?

When looking at the code snippet below, I encountered an issue with discriminating the union type using the typeof operator. function f(arg: { status: number; one: boolean } | { status: string; two: boolean }) { if (typeof arg.status === "number&q ...

"Encountering Issues with Angular's Modules and EntryComponents during Lazy Loading

Upon lazy loading an Angular module, I encountered an issue when trying to open my DatesModal that resulted in the following error: No component factory found for DatesModal. Have you included it in @NgModule.entryComponents? The declaration and entryCom ...

Limiting the scope of TypeScript types to specific keys, such as Exact/DeepExact

After coming across this specific query on SO, I wanted to delve into creating an Exact type. My attempt at implementing something akin to a DeepExact seems to be close: // Desired type that should only accept Exact versions of type Opts = { firstName?: ...

Can TypeScript be set up to include undefined as a potential type in optional chains?

Today, I encountered a bug that I believe should have been caught by the type system. Let me illustrate with an example: function getModel(): Model { /* ... */ } function processModelName(name: string) { return name.replace('x', 'y& ...

Challenges with Spreading Props in TextField Component After MUIv4 Upgrade with TypeScript

Latest Material-UI Version: 4.1.0 I'm encountering difficulties in passing props to an abstracted <TextField /> component that I've developed. Below is the snippet of code: PasswordInput.tsx import * as React from 'react' impo ...

Testbed: Issue encountered: Unable to resolve all parameters for PriDateInput component

I am facing an issue while creating an Angular Component with the help of TestBed. The error message I receive is as follows: Error: Can't resolve all parameters for PriDateInput: (?). error properties: Object({ ngSyntaxError: true }) ...