在 jsrender 上查找方法时出错,使用带有打字稿的 jsrender/jsviews

Error looking up method on jsrender, using jsrender / jsviews with typescript

我正在尝试 integrate/use jsview/jsrender 在使用 webpack-4 完成构建的打字稿项目中。由于通过 npm 安装的 jsrender/jsviews 包不包含类型定义,它们不能通过 DefinitelyTyped 获得,但 jsview/jsrender 的作者单独提供了类型定义。我将它们保存在 typings/[jsrender, jsview] 文件夹中并修改了我的 tsconfig.json 如下所示:

我的 tsconfig.json 有以下内容:

{
"compileOnSave": true,
"compilerOptions": {
    "baseUrl": ".",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "target": "es2015",
    "moduleResolution": "node",
    "declaration": false
},
"include": [
    "static/js/**/*",
    "*/static/ts/**/*.ts"
],
"exclude": [
    "node_modules",
    "**/*.spec.ts"
],
"files": [
    "./typings/jsrender/index.d.ts",
    "./typings/jsviews/index.d.ts"
]

}

然后我导入 jsrender:

import * as jsrender from 'jsrender'; 

当我尝试使用 jsrender 时:

tmpl = jsrender($).templates('Name: {{:name}}');

webpack 报错如下:

TS2339: Property 'templates' does not exist on type 'JQuery'.

jsrender 类型定义的前几行如下:

/// <reference types="jquery" />

declare module 'jsrender' {
    export = jsrender;
}

declare const jsrender: JQueryStatic;

interface JQueryStatic {
    /* var htmlString = $.render.templateName(data, myHelpersObject); // Render named template */
    render: {
        [tmplName: string]: JsViews.TemplateRender;
    };

    /* $.views.xxx ... // JsRender/JsViews APIs */
    views: JsViews.Views;

    /* $.templates(...) or $.templates.templateName: Compile/get template */
    templates: JsViews.Templates;
}

我不确定为什么 webpack 即使在调试时也会报错,如果我这样做的话:

let tmpl = jsrender($);

并在上面那行打断点,我可以看到tmpl对象确实有"templates"函数可用。

我不确定是 webpack 问题,tsconfig 问题还是我使用 jsrender 的方式。

你是对的,那些版本的 JsRender index.d.ts 和 JsViews index.d.ts 对于你的 webpack + typescript 场景是不正确的。

JsRender index.d.ts 应该这样开始:

declare module 'jsrender' {
    export = jsrender;
}

declare const jsrender: ((jquery?: JQueryStatic) => JQueryStatic) & JQueryStatic;

// ********************************** JsRender **********************************

interface JQueryStatic {
...

和 JsViews index.d.ts 应该这样开始:

declare module 'jsviews' {
    export = jsviews;
}

declare const jsviews: ((jquery?: JQueryStatic) => JQueryStatic) & JQueryStatic;

// ********************************** JsObservable **********************************

interface JQueryStatic {
...

进行这些更改后,应该可以正常工作了。

如果使用 JsRender 并将 jQuery 作为模块而不是全局加载,那么您可以通过以下方式对 .ts 文件进行编码:

import * as $ from 'jquery'; 
import * as jsrender from 'jsrender'; 

jsrender($); // load JsRender jQuery plugin methods

let tmpl = $.templates(...);

// Now use tmpl.render() etc.

事实上 jsrender($) returns $,所以上面更简单的语法等同于你的版本,(实际上并没有 运行 对抗你遇到的 typescript 声明错误问题) .

如果使用 JsViews,则改为编写

import * as $ from 'jquery'; 
import * as jsviews from 'jsviews'; 

jsviews($); // load JsRender and JsViews jQuery plugin methods

let tmpl = $.templates(...);

// Now use tmpl.render() and/or tmpl.link() etc.