Type 中缺少索引签名 - AngularJS + TypeScript 验证使用 $validators

Posted

技术标签:

【中文标题】Type 中缺少索引签名 - AngularJS + TypeScript 验证使用 $validators【英文标题】:Index signature is missing in Type - AngularJS + TypeScript validation using $validators 【发布时间】:2016-10-31 12:17:22 【问题描述】:

我正在尝试使用 AngularJS 1.5 和 TypeScript 1.7 创建一个指令,以便我可以进行一些自定义表单验证。

I've followed this example 但是当我扩展 ng.INGModelController 时,Typescript 给了我一个“类型签名缺失”

interface IOneItemRequiredValidator extends ng.INgModelController 
    $validators: 
        oneItemRequired(modelValue: any, viewValue: any) : boolean;
    ;

我检查了 $validators,它是 IModelValidators 类型,具有以下签名:

interface IModelValidators 
    [index: string]: (modelValue: any, viewValue: any) => boolean;

所以我尝试遵循这一点,现在 TypeScript 并没有抱怨,但是当我尝试访问 $validators 对象的新属性时它找不到它。

interface IOneItemRequiredValidator extends ng.INgModelController 
    $validators: 
        [oneItemRequired: string]:  (modelValue: any, viewValue: any) => boolean;
    ;



angular
    .module('app')
    .directive('oneItemRequired', () => 
        return 
            restrict: 'A',
            require: 'ngModel',
            link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes, controller: IOneItemRequiredValidator) => 
                controller.$validators.oneItemRequired = (modelValue, viewValue) => 
                        return viewValue !== null && viewValue !== undefined && viewValue.length > 0;
                    
                
            ;
        );

我是否错误地声明了我的新 IOneItemRequiredValidator 接口?谢谢!

【问题讨论】:

【参考方案1】:

我不将 Angular 1 与 TypeScript 一起使用,但一般来说,在 TypeScript 中,你给它们起的名字根本没有区别。您只是说您接受任何未在界面中命名的额外属性。

这意味着实际的 Angular 声明文件应该在 IModelValidators 声明中添加该位。详情请见here。

老办法的问题在于,单函数oneItemRequired的对象类型与IModelValidators类型不兼容。

您可以通过以下两种方式之一解决此问题:

(1) 把索引器放回去就好了,比如:

interface IOneItemRequiredValidator extends INgModelController 
    $validators: 
        oneItemRequired(modelValue : any, viewValue : any) : boolean;
        [otherProps: string]:  (modelValue: any, viewValue: any) => boolean;
    ;

A simple non-Angular example

(2) 手动扩展接口,如:

interface IOneItemRequiredNgModelValidators
    extends ng.IModelValidators 
        oneItemRequired(modelValue : any, viewValue : any) : boolean;       
    

interface IOneItemRequiredValidator extends ng.INgModelController 
    $validators: IOneItemRequiredNgModelValidators

A simple non-Angular example

第一个代码较少,仅旨在真正为该工具提供服务,只是有点hacky。第二个感觉很酷,但更多的是为了工具。所以,我会让你选择:)

让我知道他们是否适合你。

干杯,

【讨论】:

感谢@Meligy 花时间提出如此全面的答案并在操场上添加示例。我最终选择了第二个选项,因为它看起来更清晰。它现在是一种享受!干杯

以上是关于Type 中缺少索引签名 - AngularJS + TypeScript 验证使用 $validators的主要内容,如果未能解决你的问题,请参考以下文章

无法获取属性,因为在 null 或 undefined [1] 中缺少声明预期键/值类型的索引签名

type 'typeof globalThis' 没有索引签名

错误 TS2349:无法调用其类型缺少调用签名的表达式。类型 ' ; ' 没有兼容的调用签名

打字稿“新”表达式,其目标缺少构造签名,隐含具有“任何”类型

无法调用类型缺少调用签名的表达式...没有兼容的调用签名

打字稿:类型“”没有索引签名