Как использовать внешнюю библиотеку без машинописного текста из машинописного текста без .d.ts?

100

Я определил их в своем файле .html:

<script type="text/javascript" src="bower_components/tree.js/tree.min.js"></script>
<script type="text/javascript" src="bower_components/q/q.js"></script>
<script type="text/javascript" src="test.js"></script>

Затем в test.js:

 var myTree = Tree.tree({})

Но в Typescript появляется сообщение: «Не удается найти имя" Дерево "».

Я также попытался скомпилировать --module amdи разместить import Tree = require("model/tree");в верхней части файла test.js, но снова возникла ошибка: Cannot find external module 'model/tree'.однако очевидно, что это должен быть действительный импорт, см. Здесь, где он был определен: https://github.com/marmelab/tree .js / blob / master / src / main.js

Я не хочу писать файлы .d.ts для каждого отдельного внешнего файла javascript, который я хочу использовать, серьезно ли это то, что Typescript хочет от меня?

Blub
источник
1
Вам не нужно записывать файлы .d.ts. См. Stackoverflow.com/questions/27273489/… для примера
xmojmr
интересно, это все равно потребует от меня объявления объектов. У меня создалось впечатление, что Typescript полностью совместим с javascript. Я думаю, это имеет смысл с точки зрения Typescript, ему как-то нужно читать код, и если бы он не имел хороших ссылок, это были бы ошибки.
Blub

Ответы:

124

Я не хочу писать файлы .d.ts для каждого отдельного внешнего файла javascript, который я хочу использовать, серьезно ли это то, что Typescript хочет от меня?

Нет. Самое простое и быстрое решение - просто сказать ему, что есть какая-то переменная Tree. Это очень просто:

declare var Tree:any; // Magic
var myTree = Tree.tree({})

TypeSafety - это скользящая шкала в TypeScript. В этом случае вы только говорите компилятору, что есть что-то, Treeчто вы будете управлять, и не заботитесь о большой безопасности типов, кроме того факта, что это есть .

Больше

IMHO: declare var Tree:any;синтаксис строки намного проще, чем у других инструментов проверки JS, которые вы бы написали, чтобы объявить об использовании переменных, которых нет в вашем коде.

Обновить

interface ITree {
    .. further methods and properties...
}

interface ITreeFactory {
    tree(input: { [key: string]: any }): Itree
};

declare var Tree: ITreeFactory; // magic...
басарат
источник
Когда я использовал этот метод, я жаловался. Мне пришлось использовать метод, описанный Антоном ниже. Однако ваш пробег может отличаться! Спасибо за ответ басарат.
Tiz
вы также можете указать тип как интерфейс вместо любого, который обеспечит лучший интеллект.
Akash Kava
24

Вы можете сами определить 'require' и использовать недокументированную функцию amd-dependency в TypeScript:

/// <amd-dependency path="model/tree" />
declare var require:(moduleId:string) => any;
var Tree = require("model/tree");

Директива amd-dependency указывает компилятору включить ваш модуль для «определения» аргументов в сгенерированный код: см. образец здесь .

Вы также можете проверить очень хорошую статью, в которой объясняется, как использовать TypeScript с RequireJS.

Но обратите внимание, что без написания правильных определений TypeScript для существующего кода вам не будет предоставлена ​​никакая информация о типе, и поэтому вы не получите проверки безопасности типов, расширенное завершение кода в инструментах и ​​т. Д. Итак, ваше «Дерево» на самом деле будет иметь тип «any» и фактически будет динамической частью JS внутри другого кода TS.

Антон
источник
Не лучшая идея при использовании веб-пакета, веб-пакет потребует, чтобы этот модуль присутствовал при транспиляции ...
Акаш Кава