我正在尝试在客户端和服务器中使用现有的js库(validate.js)。
我使用npm安装它,所有内容都为服务器和客户端编译 在服务器中使用它时效果很好,但是当我在浏览器中执行它时会抛出错误。
在这两种情况下都使用相同的文件:
import validate = require("validate.js");
export function RequestValidator(data: any): any {
return (validate as any)(data, constraints, { allowEmpty: true });
}
validate
被声明为any
,否则我得到:
TS2349:无法调用类型缺少调用签名的表达式。
我正在使用的.d.ts
是:
declare module "validate.js" {
export interface ValidateJS {
(attributes: any, constraints: any, options?: any): any;
async(attributes: any, constraints: any, options?: any): Promise<any>;
single(value: any, constraints: any, options?: any): any;
}
export const validate: ValidateJS;
export default validate;
}
该模块只导出一个函数,并且在服务器中运行良好,但在客户端调用此函数时,我得到:
Uncaught TypeError: validate is not a function(…)
使用目标commonjs
为服务器编译代码:
"use strict";
const validate = require("validate.js");
...
客户端system
:
System.register(["validate.js"], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var validate;
...
return {
setters:[
function (validate_1) {
validate = validate_1;
}],
...
调试时,validate
确实不是它的功能:
validate: r
EMPTY_STRING_REGEXP: (...)
get EMPTY_STRING_REGEXP: function()
set EMPTY_STRING_REGEXP: function()
Promise: (...)
get Promise: function()
set Promise: function()
__useDefault: (...)
get __useDefault: function()
set __useDefault: function()
async: (...)
get async: function()
set async: function()
capitalize: (...)
get capitalize: function()
set capitalize: function()
cleanAttributes: (...)
get cleanAttributes: function()
set cleanAttributes: function()
...
知道发生了什么以及为什么它在浏览器中以这种方式运行?
答案 0 :(得分:3)
使用"module": "system"
编译时,节点兼容导入
import validate = require("validate.js");
不再有效 - 您为validate
获得的值是一个模块,而不是一个函数。这可能是打字稿中的错误,或者可能是设计 - 我不知道。 (更新:从github评论发给JsonFreeman here,它看起来像设计:you get the module object with a set of properties including one named default
)。
有几种解决方法。
首先,您可以自己轻松进行转换 - 您需要的功能是作为模块的default
属性提供的,因此该行将修复它:
validate = validate.default ? validate.default : validate;
或者,即使浏览器也可以使用"module": "commonjs"
进行编译,因此typescript将生成工作代码,systemjs将自动检测模块的格式。
或者最后,你仍然可以使用"module": "system"
进行编译,但导入validate.js
就像它的打算一样:
import validate from 'validate.js';
这样你就不必对any
进行任何强制转换,而typescript会为default
属性生成必要的访问权限,但缺点是它在导入时在节点中根本不起作用那样。