Ошибка при поиске метода на jsrender, используя jsrender/jsviews с typescript

Я пытаюсь интегрировать/использовать jsview/jsrender в проекте typescript со сборкой, выполненной с использованием webpack-4. Поскольку пакет jsrender/jsviews, установленный через npm, не содержит определений типов, они не доступны через 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: свойство «шаблоны» не существует для типа «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;
}

Я не уверен, почему веб-пакет жалуется даже при отладке, если я просто делаю:

let tmpl = jsrender($);

и поставьте точку останова на строку выше, я вижу, что объект tmpl имеет доступную функцию «шаблоны».

Я не уверен, является ли это проблемой веб-пакета, проблемой tsconfig или тем, как я использую jsrender.


person Divick    schedule 14.12.2018    source источник


Ответы (1)


Вы правы, эти версии 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 {
...

С этими изменениями все должно работать правильно.

Вот как вы можете кодировать свой файл .ts, если используете JsRender и загружаете jQuery как модуль, а не глобально:

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

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

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

// Now use tmpl.render() etc.

На самом деле jsrender($) возвращает $, поэтому приведенный выше более простой синтаксис эквивалентен вашей версии (и фактически не сталкивается с проблемой ошибки объявления машинописного текста, с которой вы столкнулись).

Если вы используете 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.
person BorisMoore    schedule 15.12.2018
comment
Спасибо за ответ. Я думаю, это должно сработать. Просто я отказался от jsrender/jsviews, так как их синтаксис казался слишком сложным. В итоге я отправил предварительно обработанный html с сервера вместо возврата Json. Не лучшее, что можно сделать, но работает для меня. - person Divick; 18.12.2018