Can you define the type of binding value in AngularJS 1.5(6) using TypeScript?

I am looking to define the type of binding items so that I am able to utilize components similar to functions.

For instance, consider a component:

angular.module('app').component('navBar', new NavBar());

 class NavBar{
    public bindings:{};
    constructor(){
        this.bindings={ 
            navInfo:'<'
        }
    }
}

The expected data structure is as follows:

export interface INavInfo {
    text: string;
    icon: string;
    OnClick: Function;
}

In order to avoid any errors, I need to pass in data like this:

{
  text: 'Maintenance',
  icon: 'assessment',
  OnClick: () => {....}
}

Is there a way to enforce that only objects with the structure defined in INavInfo can be passed into navInfo?

Answer №1

Your code isn't clear on where you want TypeScript compilation to fail. It seems related to how you pass the navInfo information.

Check out the example of using heroes in Angular components from the official documentation: https://docs.angularjs.org/guide/component

In the example, data is passed to components in the index.js file:

angular.module('heroApp', []).controller('MainCtrl', function MainCtrl() {
    this.hero = {
    name: 'Spawn'
  };
});

To ensure correct data passing in your component with TypeScript, mark the this.hero variable as type INavInfo in your TS controller:

private hero: INavInfo;

If someone forgets to use this specific type in another controller but uses the same component, TypeScript compilation won't show errors. On the flip side, if everyone correctly declares INavInfo wherever the component is used, any changes to properties will cause errors where needed.

Answer №2

Assuming the question is about navInfo being a part of component bindings declaration and you want to...

<nav-bar navInfo="vm.navInfo"></nav-bar>

in the view
and have "vm.navInfo" checked against INavInfo.

The answer is no.

Since you will be instantiating your component within an HTML view, and currently there is no tool that supports type-checking TypeScript in HTML markup. Angular also does not provide type binding characteristics, only the 'key' for binding and its behavior, as it is an Angular convention rather than a language feature.

Even if you create your component with inline HTML code all in one file within Webstorm, which is very Angular 1.x friendly,

You could consider adding run-time checking (although it may not be advisable).

import * as angular from "angular";

export interface INavInfo {
    text: string;
    icon: string;
    OnClick: Function;
}

function isNavInfo(x: any): x is INavInfo {
    return x && typeof x.text === "string"
        && typeof x.icon === "string"
        && typeof x.OnClick === "function";
}

class NavBar implements angular.IController {

    navInfo?: INavInfo;

    $onInit = () => {

    };

    $onChanges? = (onChangesObj: angular.IOnChangesObject) => {
        if (this.navInfo && !isNavInfo(this.navInfo)) {
            throw "Nav Info is Not NavInfo";
        }
    };

    clicked = ()=> {
        if(this.navInfo && this.navInfo.OnClick){
            this.navInfo.OnClick();
        }
    }
}

class OtherController {
    navInfo: INavInfo ;
    constructor(){
        this.navInfo = {
            text: "Hello",
            icon: "home",
            OnClick: ()=>{
                console.log("link clicked!")
            }
        };
    }
} 

angular.module('NavBarTest', [])
    .component(
        'navBar', {
            template: `<!-- there's No Type Checking here -->
                        <ul>
                            <li>
                                <a class="navText" href="" ng-click="$ctrl.clicked">
                                {{$ctrl.navInfo.text}}
                                <i class="naIvIcon">{{$ctrl.navInfo.icon}}</i>
                                </a>                        
                            </li>
                       </ul>>`,
            bindings: {
                navInfo: '<'
            },
            controller: NavBar,
            // controllerAs: '$ctrl'
        }
    )
    .component("navBarUser", {
        template: ` <!-- there's No Type Checking here -->
            <nav-bar nav-info="$ctrl.navInfo" ></nav-bar>
        `,
        controller: OtherController,
        // controllerAs: '$ctrl'
    });

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

Sending the HTML input value to a Knockout view

Can someone assist me with a dilemma I'm facing? Within CRM on Demand, I have a view that needs to extract values from CRM input fields to conduct a search against CRM via web service. If duplicate records are found, the view should display them. Be ...

Navigating VSCode for Correct Import Setup

My root app directory has a structure consisting of the following folders: /app/ /environments/ Within the /app/ folder, there is a file named Helper.ts located in the helpers/ subdirectory: /app/helper/Helper.ts Inside this file, I attempted to import ...

Encountering a 'No overload matches this call.' error when using ApexCharts with Typescript and ReactJS

As a newcomer to Typescript, I am gradually familiarizing myself with this powerful tool. After fetching the OHLCV data from coinpaprika and passing it to ApexCharts, I encountered an issue while trying to map the raw data: ERROR in src/routes/Chart.tsx:3 ...

Is there a way to automatically adjust the position of a tooltip div based on its location relative to the screen in AngularJS?

I've implemented AngularJs to create a grid with repeated li elements, each displaying a description box when hovered over. However, I am facing an issue where the description box goes off-screen when hovering over items on the right side of the grid. ...

How can I incorporate the LIKE operator in a query when dealing with PostgreSQL's String array type using TypeORM?

My database backend is PostgreSQL and I have a TypeORM object simplified as follows: @Entity() @Index(['name'], {unique: true}) export class Foo extends BaseEntity { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: st ...

Using Typescript to define property types based on their respective values

Is it possible to set a property type based on the property value? For example, if the command is: If 'set' then the payload must be PayloadSet If 'put' then the payload must be PayloadPut If 'del' then the payload must be ...

Transform Observable RxJS into practical results

In a straightforward scenario, I have an upload action on the page that looks like this: onUpload$: Subject<SomeUpload> = new Subject<SomeUpload>(); uploadAction$: Observable<Action> = this.onUpload$.map(entity => this.someActionServi ...

Error: The JavaScript variable 'undefined' is being used as a function, which is incorrect. This error occurs when trying to execute the function `mockBackend

I am currently working on unit testing an AngularJS controller using Karma and Jasmine. Below is the test suite I have created: describe('Controllers', function(){ var $scope, ctrl; beforeEach(module('curriculumModule')); ...

Troubleshooting typescript error in styled-components related to Material-UI component

When using typescript and trying to style Material UI components with styled-components, encountering a type error with StyledComponent displaying Type '{ children: string; }' is missing the following properties import React, { PureComponent } f ...

Angular Material Datepicker: Changing the input field format when the field value is updated

Currently, I am utilizing a mat-date-rang-input component from Angular Material. To customize the date format to dd/MM/yyyy, I made adjustments within Angular Material which is functioning correctly. <mat-form-field ngClass="filters_dateInterval&qu ...

An issue arises when using enums in TypeScript

Let's analyze this demonstration. Initially, an enum is created as follows: enum myEnum { a = 'a', b = 'b' } The next step involves creating a similar enum but with the addition of one more numeric value! This alteration is c ...

What is the best way to limit data loading when tabs are clicked in an AngularJS application?

My application has 2 tabs and all data is fetched from an API response. Initially, all data is loaded at once. The two tabs are: Tab 1 Tab 2 By default, Tab 1 is always active. I only want to load data for Tab 1 initially and not for Tab 2. When I c ...

Creating a basic Angular 1 application from scratch

Currently, I am in the process of setting up a small application with Angular 1 to enhance my skills (yes, we are still using version 1 at my workplace and I want to familiarize myself with it). Most of the application is working fine, but as soon as I in ...

What is the best way to specifically install the angular-ui-router.js file without the whole npm source code solution?

After installing the angular package using npm, I found the necessary JS files in the angular root directory. $npm install angular However, when installing the angular-ui-router package, I received the entire source code solution along with the required ...

What is the meaning of '=>' in typescript/javascript?

I keep coming across lots of '=>' in the code I found on the internet. Could someone please explain it to me as if I were 5 years old? (I'm searching for the specific code, and I'll share it here once I locate it).. Found it: ...

Using the spread operator to modify an array containing objects

I am facing a challenge with updating specific properties of an object within an array. I have an array of objects and I need to update only certain properties of a single object in that array. Here is the code snippet I tried: setRequiredFields(prevRequir ...

Discovering new bugs in VSCode Playwright Tests but failing to see any progress

This morning, everything was running smoothly with debugging tests. However, after a forced reboot, I encountered an issue where it seems like the debugger is running, but nothing actually happens. This has happened before, but usually resolves itself. Unf ...

The Next.js build encountered an error - unable to locate function in next/script module

While constructing a CMS using next.js, one of the key components is media management through Cloudinary. The integration of the Cloudinary Media Library widget was successful during development using next/script. However, an error has now emerged that pre ...

Setting a Value?

Within the services.js/Cordova file, I am encountering an issue with the following code: .factory('GCs', ['$http', function($http) { var obj= {}; $http.post("mydomina.com?myrequest=getbyid", { "id": "1"} ) ...

How to enable cross-origin resource sharing

While using $resource for making http calls, I encountered an issue with my backend application being deployed on a different port. When attempting to fetch data from the server using the request method(GET), my browser automatically attaches the request m ...