2

我正在为敲除验证插件编写 TypeScript 定义文件。我坚持的一件事与该库中如何定义新的验证规则有关。

创建基本同步验证器的ko.validation方法如下:

ko.validation.rules['myrulename'] = {
    message: 'default message to display when validation fails',
    validator: function (value, params) {
        // use value and params to evaluate rule, 
        // then return true if valid, false if invalid
    }
}

这很简单,但是创建异步验证器的方法略有不同:

ko.validation.rules['myrulename'] = {
    async: true,
    message: 'default message to display when validation fails',
    validator: function (value, params, callback) {
        // use value and params to evaluate rule, 
        // then invoke callback to indicate pass / fail
        // this function does not return a bool (it is void)
    }
}

异步回调可以采用 bool(用于验证通过/失败)或对象文字(isValid用于通过/失败,并message更改验证消息)。为此,我创建了以下内容:

interface KnockoutValidationAsyncCallbackArgs {
    isValid: bool;
    message: string;
}

interface KnockoutValidationAsyncCallback {
    (result: bool): void;
    (result: KnockoutValidationAsyncCallbackArgs): void;
}

这是我的精简版,KnockoutValidationStatic它公开了规则数组。我还为规则数组创建了一个特殊接口来指定字符串索引:

interface KnockoutValidationRulesArray extends Array {
    [index: string]: KnockoutValidationRule;
}

interface KnockoutValidationStatic {
    rules: KnockoutValidationRulesArray;
    ... other members defined on this interface
}

interface KnockoutStatic {
    validation: KnockoutValidationStatic;
}

我坚持的是KnockoutValidationRule. 我尝试了以下方法:

interface KnockoutValidationRule {
    async?: bool;
    message: string;
    validator(value: any, params: any): bool;
    validator(value: any, params: any, callback: KnockoutValidationAsyncCallback): void;
}

这适用于同步验证器声明。但是,当我创建一个异步时,我收到以下错误:

无法转换'{消息:字符串;验证器:(值:任意,参数:任意,回调:KnockoutValidationAsyncCallback)=> void }' to 'KnockoutValidationRule':类型为'{ message: string; 的属性'validator'的类型;验证器:(值:任意,参数:任意,回调:KnockoutValidationAsyncCallback)=> void;}' 和 'KnockoutValidationRule' 不兼容:

'(value: any,params: any,callback: KnockoutValidationAsyncCallback) => void' 和 '{ (value: any,params: any): bool; 类型的调用签名 (值:任意,参数:任意,回调:KnockoutValidationAsyncCallback):无效;} 不兼容:

调用签名需要 2 个或更少的参数

我还考虑过将回调作为可选参数,但这不起作用,因为函数根据签名返回不同的值(没有第三个参数的布尔值,如果存在第三个参数则为 void)。

我在这里做错了什么?我的字符串索引数组的规则有问题吗?是否可以根据这个库的工作方式创建一个 TypeScript 接口?

更新 1

看起来我在KnockoutValidationRule界面中的重载方面走在了正确的轨道上。我刚刚发现,如果我ko.validation.rules从 a更改KnockoutValidationRulesArray为 a KnockoutValidationRule[],我的测试代码对于同步和异步验证器都可以正常编译......

interface KnockoutValidationStatic {
    //rules: KnockoutValidationRulesArray; // this breaks it
    rules: KnockoutValidationRule[] // this fixes it
    ... other members defined on this interface
}

我是在声明数组错误吗?

更新 2

这是我用来测试定义的一些示例代码:

/// <reference path="../../ko/knockout-2.2.d.ts" />
/// <reference path="../../ko/knockout.validation.d.ts" />

module TestKoVal {

    ko.validation.rules['test1'] = {
        message: '',
        validator: (value: any, params: any): bool => {
            return false;
        }
    }

    ko.validation.rules['test2'] = {
        async: true,
        message: '',
        validator: function (value: any, params: any, callback: KnockoutValidationAsyncCallback): void => {
            callback(false);
            callback(true);
            callback({ isValid: false, message: 'custom' });
        }
    }
}

就像我说的,当ko.validation.rules是 a时,上面的编译很好KnockoutValidationRule[]。当我将其更改为KnockoutValidationRulesArray.

4

2 回答 2

0

我想我可能已经弄清楚为什么上述方法不起作用了。在 javascript 中,当您使用带有字符串作为索引器的 [] 数组语法时,您并没有创建通常意义上的数组。相反,该语法只是将属性添加到对象。以下是功能等效的:

ko.validation['test1'] = { ... };
ko.validation.test1 = { ... };
于 2012-12-23T15:38:41.170 回答
0

您可以通过修改 KnockoutValidationRule 来解决此问题:

export interface KnockoutValidationRule {
    async?: bool;
    message: string;
    validator: (value: any, params: any, callback?: KnockoutValidationAsyncCallback): bool;
}

并在使用它的地方进行相应的更改:

ko.validation.rules['test2'] = {
    async: true,
    message: '',
    validator: (value: any, params: any, callback?: KnockoutValidationAsyncCallback): bool => {
        callback(false);
        callback(true);
        callback({ isValid: false, message: 'custom' });
    }
}

这统一了两个方法签名。验证方法实际上不需要返回布尔值,因此声明该方法返回布尔值的事实主要是外观/美学问题。

在codeplex 站点上围绕这个展开讨论可能是值得的,因为我怀疑这代表 JavaScript 库中不常见的使用。

于 2012-12-23T16:38:22.580 回答