Может ли Typescript импортировать Webpack UMD?

Используя TypeScript, есть ли способ import модуль, который был упакован в веб-пакет UMD (определение универсального модуля)? Например:

npm install knockback

Файл.js (node_modules/knockback/knockback.js) начинается так:

(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory(require("knockout"), require("backbone"), ....
    else if(typeof define === 'function' && define.amd)
        define(["knockout", "backbone", "underscore"], function webpackLoadOptionalExternalModuleAmd( ....
        });
    else if(typeof exports === 'object')
        exports["kb"] = factory(require("knockout"), require("backbone"), require("underscore"), (function ....
    else
        root["kb"] = factory(root["ko"], root["Backbone"], root["_"], root["jQuery"]);

Когда я пытаюсь импортировать это в файл.ts, tsc выдает ошибку:

import * as k from 'knockback/knockback';

TS2307: Build: Cannot find module 'knockback/knockback'.

Могу ли я что-нибудь сделать, кроме редактирования файла knockback.js, чтобы убедить tsc импортировать этот.js? Я использую Typescript 1.8.

2 ответа

Решение

Когда я пытаюсь импортировать это в файл.ts, tsc выдает ошибку:

Вы можете использовать файл определения типа довольно легко

файл knockback.d.ts

declare module 'knockback/knockback' {
    var foo: any;
    export = foo;
}

К вашему сведению, для тех, кто в конечном итоге пытается использовать knockback.js через Typescript, уже существует knockback.d.ts файл, доступный от DefinitiveTyped. Тем не менее, существующие.d.ts не включает в себя export, поэтому не может использоваться с внешними модулями. Основываясь на ответе Басарата, я изменил файл.d.ts следующим образом:

1) Добавить в конец следующее:

declare module "knockback" {
    export = Knockback;
}

2) Удалить declare var kb: Knockback.Static с конца.

3) Удалить interface Static extends Utils { обернуть и переместить все внутри Static Интерфейс для области имен пространства. Пример:

Старый:

interface Static extends Utils {
    ViewModel;
    CollectionObservable;
    collectionObservable(model?: Backbone.Collection<Backbone.Model>, options?: CollectionOptions): CollectionObservable;
    observable(
        /** the model to observe (can be null) */
        model: Backbone.Model,
        /** the create options. String is a single attribute name, Array is an array of attribute names. */
        options: IObservableOptions,
        /** the viewModel */
        vm?: ViewModel): KnockoutObservable<any>;
    ...
}

Новое:

    function collectionObservable(model?: Backbone.Collection<Backbone.Model>, options?: CollectionOptions): CollectionObservable;
    function observable(
        /** the model to observe (can be null) */
        model: Backbone.Model,
        /** the create options. String is a single attribute name, Array is an array of attribute names. */
        options: IObservableOptions,
        /** the viewModel */
        vm?: ViewModel): KnockoutObservable<any>;
    ...

После этих изменений использование выглядит так:

import * as kb from 'knockback';

class MyViewModel extends kb.ViewModel {
    public name: KnockoutObservable<string>;

    constructor(model: Backbone.Model) {
        super();

        this.name = kb.observable(model, "name");
    }
}

var model = new Backbone.Model({ name: "Hello World" });
var viewModel = new MyViewModel(model);

kb.applyBindings(viewModel, $("#kb_observable")[0]);
Другие вопросы по тегам