是否可以使用typescript在angularjs 1.5(6)中指定绑定值的类型

时间:2016-12-22 02:51:10

标签: angularjs typescript

我想指定绑定项的类型。所以我可以像使用函数一样使用组件。

例如,

。我们有一个组件

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

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

,预期数据为

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

我期望传递的是(否则会抱怨错误输入)

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

有没有办法限制navInfo中的类型传递是INavInfo的类型?

2 个答案:

答案 0 :(得分:0)

我无法通过您希望TypeScript编译中断的代码“where”清楚地看到。我想这与你有很多关系传入 navInfo信息。

让我们在组件的角度文档中获取英雄示例 https://docs.angularjs.org/guide/component

我看到你数据传递给该示例中的组件的方式在index.js文件中:

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

在此示例中,使用 TypeScript 确保将所有详细信息正确传递到组件的唯一方法是将this.hero变量标记为TS控制器中的类型INavInfo

private hero: INavInfo;

如果有人忘记在另一个控制器中使用此特定类型并使用相同的组件,那么TypeScript编译将不会中断。

另一方面,假设每个人都做得很好并明确宣布INavInfo你使用这个组件的所有地方......使用这种类型的所有地方都会在时你需要更改一个属性名称或删除它。

答案 1 :(得分:0)

如果我的问题是对的。 navInfo是组件绑定声明和的成员 你想做...

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

在视图中 和&#34; vm.navInfo&#34;要进行型式检查
反对INavInfo。

然后答案是否定的。

因为您将在HTML视图中实例化您的组件,  据我所知目前没有工具,  支持这种情况,  验证HTML标记中的检查打字稿。 没有角度提供类型的绑定,简单地声明键#39;绑定到它的绑定行为。 因为语言功能不支持角色约定

即使您声明了组件 内联html将所有代码保存在一个文件中 在Webstorm中,这是非常有角度的1.x友好

但你可以添加运行时检查(我不认为它的好主意......)

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'
    });