Steps for performing a runtime cast

When working on a web application written in TypeScript, there is a feature where users can add additional JavaScript functions that will be parsed at runtime (new function(Function as String)) for execution. These functions should return an object defined in TypeScript as class Script. However, if the script object does not contain specific functions, it is considered invalid. My goal is to throw an exception if any required functions are missing.

Using a TypeScript cast is not viable as it is a compile-time operation.

One approach I thought of is to assign the parsed object to the Script object's constructor and then check for missing properties. Here is a rough example to illustrate the idea:

export class Script {
    constructor(object: Script) {
    this.getDefaultValue = object.getDefaultValue;
    this.isAvailable = object.isAvailable;
    this.isValid = object.isValid;
    this.isInRange = object.isInRange;
    this.isDataFormat = object.isDataFormat;

    for (let property in this){
        if (!this[property]){
        throw new Error(property + ' is missing.');
        }
    }
    }
    getDefaultValue: any;
    isAvailable: (containerSetId: number) => boolean;
    isValid: (value: any) => boolean;
    isInRange: (value: any) => any;
    isDataFormat: (value: any) => boolean;
}

However, I am wondering if there is a more elegant solution to handle this scenario.

Answer №1

Unfortunately, that code won't work because:

class A {
    member1: string;
    member2: number;
    member3: boolean;

    constructor() {
        this.member3 = true;
    }
}

After compilation, it looks like this:

var A = (function () {
    function A() {
        this.member3 = true;
    }
    return A;
}());

Notice that member1 and member2 are not included in the compiled JavaScript code.
To ensure you have all necessary properties at runtime, you must track them like this:

class Script {
    getDefaultValue: any;
    isAvailable: (containerSetId: number) => boolean;
    isValid: (value: any) => boolean;
    isInRange: (value: any) => any;
    isDataFormat: (value: any) => boolean;

    required = [
        "getDefaultValue",
        "isAvailable",
        "isValid",
        "isInRange",
        "isDataFormat"
    ]

    constructor(object: Script) {
        this.getDefaultValue = object.getDefaultValue;
        this.isAvailable = object.isAvailable;
        this.isValid = object.isValid;
        this.isInRange = object.isInRange;
        this.isDataFormat = object.isDataFormat;

        for (let property of this.required) {
            if (!this[property] || typeof this[property] !== "function") {
                throw new Error(property + ' is missing.');
            }
        }
    }
}

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

Creating a private variable to perform a select_sum query

I have defined private variables in my CodeIgniter code like this: private $table = 'phone'; private $column_order = array(null, 'name', 'price'); private $type = array('type'); private $battery_consumption = array ...

Getting information from MongoDB using Node.js and Angular

Currently, I am facing difficulty in retrieving data from MongoDB (I'm also using Mongoose) and sending it to Angular in order to populate the ng-repeat list with the retrieved data. I have managed to either display the data on a blank page directly f ...

A guide on showing POST values from javascript XMLHttpRequest() in php

I have encountered an issue where I am using the XMLHttpRequest() javascript function to send parameters in Json format to another php page, but for some reason $_POST['appoverGUID'] is not receiving the posted values. Below is my Javascript cod ...

Tracking the advancement of synchronous XMLHttpRequest requests

Within the client-side environment, there exists a File-Dropzone utilizing the HTML5 File-API which allows users to drop multiple files for uploading to the server. Each file triggers the creation of a new XMLHttpRequest Object that asynchronously transfer ...

Utilizing Vue.js 2.x to send a REST API request with a collection of objects

I currently have an array of objects stored in state, and my goal is to send this entire structure to a back end API for processing and receive a new set of values in return. Below is a simplified representation of this structure as viewed in the develope ...

Populating a form field using another input

I am facing an issue with retrieving the price of a product in one field when the product name is selected in another field on a simple POS system. It works fine for the first product, but when I add another row for the next product, the price does not dis ...

Execute the validation directive using the digest cycle

This particular directive is designed to determine whether a given value exists within the associated datalist or not. It functions flawlessly when I input text into the field, but it fails to work properly if the datalist undergoes changes as a result o ...

Merging two arrays with lodash for a seamless union

Here are two arrays I'm working with: arr1 = [ { "key1": "Value1" }, { "key2": "Value2" }, { "key3": "Test3" }, { ...

Angular Error: The first argument has a property that contains NaN

Struggling with a calculation formula to find the percentage using Angular and Typescript with Angularfire for database storage. Encountered an error stating First argument contains NaN in property 'percent.percentKey.percentMale. The properties are d ...

react-native-track-player failing to play song requested from Express server

I set up an expressjs server with a 'songs' route that serves .mp3 files. Here is the code for the Songs Route: import express from "express" const path = require("path") const router = express.Router() ... router.get(" ...

"Wordpress Pluto theme: A stellar choice for your

I'm trying to add a link in my main template.index file that will redirect to one of my pages when clicked on the JavaScript button at the top in Pluto theme. Currently, the text is there but clicking on it opens something I don't want. Here&apo ...

Guide on utilizing angularjs $q.all() method with a dynamically generated set of promises

I am currently facing an issue with using $q.all() to wait for multiple promises to be resolved. I have created an array of promises and passed it to the all() method, but it doesn't seem to be working as expected. The promises in the array are gener ...

Selecting ion-tabs causes the margin-top of scroll-content to be destroyed

Check out the Stackblitz Demo I'm encountering a major issue with the Navigation of Tabs. On my main page (without Tabs), there are simple buttons that pass different navparams to pre-select a specific tab. If you take a look at the demo and click t ...

FabricJS Canvas with a React DropDown Feature

While I have successfully created a TextBox on FabricJS Canvas, creating a Dropdown component has proven to be a challenge. The fabric.Textbox method allows for easy creation of text boxes, but no such built-in method exists for dropdowns in FabricJS. If y ...

Is there a method available to retrieve the data values stored within these objects?

Looking at the image below, I have data that includes a Data array in JSON format. https://i.sstatic.net/WHdUw.png The Data array contains key values such as condition_type and other related values. In order to extract individual values, I am using the ...

Attempting to create a JavaScript function that will show a JSON array when the next button is clicked

I am facing an issue with displaying a JSON array based on specific start and end indices. Even though I managed to display the entire array, the first button click does not seem to work as expected. Upon clicking the first button, an error message "this.d ...

Using scrollIntoView() in combination with Angular Material's Mat-Menu-Item does not produce the desired result

I am facing an issue with angular material and scrollIntoView({ behavior: 'smooth', block: 'start' }). My goal is to click on a mat-menu-item, which is inside an item in a mat-table, and scroll to a specific HTML tag This is my target ...

Launch the game within the gaming application

I am looking to incorporate a game within another game... Here's what I mean: Open the app: Pandachii Next, navigate to the 4th button (game pad). When we click on the game icon, I want to launch another game (located below the Pandachii window - c ...

Ensure that the flex item spans the entire width of the page

I'm struggling to make my audio-player resize properly to fit the full width of my page. I can't seem to figure out what I'm missing or doing wrong... (Current Look) https://i.sstatic.net/tEtqA.png I'm attempting to utilize HTML cust ...

Viewing information from the database without the need to refresh the page

HTML <textarea>Enter your question here</textarea><button class="askButton">SUBMIT</button> Upon clicking the button, the question is stored in the database using Ajax, jQuery, and Laravel. However, the question only appears after ...