如何在TypeScript中使用一个外部非TypeScript库而无需.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 报错说:"无法找到名称为 'Tree' 的内容"
我还尝试使用 --module amd 编译,并在 test.js 文件顶部放置了 import Tree = require("model/tree");,但它再次出现了错误:无法找到外部模块 'model/tree',然而显然这应该是一个有效的导入,请看这里它是如何定义的:https://github.com/marmelab/tree.js/blob/master/src/main.js不想为我想要使用的每个外部 JavaScript 文件编写 .d.ts 文件,难道这就是 TypeScript 要求我做的吗?

1
不必编写 .d.ts 文件。请参见 https://dev59.com/NYXca4cB1Zd3GeqPMbrz 以获取示例。 - xmojmr
有趣的是,这仍然需要我声明对象。我原本以为Typescript与javascript完全兼容。从Typescript的角度来看,这似乎是有道理的,因为它需要读取代码,如果没有引用,那么就会出现错误。 - Blub
2个回答

127

我不想为每个要使用的外部JavaScript文件编写.d.ts文件,这难道是TypeScript想让我做的吗?

不是的。最简单/最快的解决方案只是告诉它有一个名为Tree的变量存在。方法非常简单:

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

在TypeScript中,类型安全是一个滑动的标尺。在这种情况下,你只告诉编译器有一个叫做Tree的东西需要管理,并且除了它存在这个事实之外,你并不关心太多的类型安全。

更多

个人认为:declare var Tree:any;这行代码比其他JS验证工具要求你编写的声明未出现在代码中的变量使用的语法要简单得多。

更新

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

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

declare var Tree: ITreeFactory; // magic...

当我使用这个方法时,它对我抱怨不止。我必须使用Anton在下面列出的方法。尽管如此,你的结果可能会有所不同!感谢basarat提供的答案。 - Tiz
你可以将类型指定为接口而不是任何类型,这样会提供更好的智能感知。 - Akash Kava

24
你可以自己定义 'require' 并使用 TypeScript 中未记录的 amd-dependency 特性:

您可以自行定义 'require' 并使用 TypeScript 中未记录的 amd-dependency 特性:

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

'amd-dependency'指令将告诉编译器在生成的代码中包含您的模块作为“define”参数:在此处查看样例

您还可以查看这篇非常好的文章,它解释了如何使用TypeScript与RequireJS。

但请注意,如果没有为现有代码编写正确的TypeScript定义,您将不会获得任何类型信息,因此您将无法获得类型安全检查、工具中的高级代码完成等功能。因此,您的'Tree'实际上将是“any”类型,并且实际上将成为其他TS代码内部的动态JS代码。


在使用webpack时,这并不是一个好主意,因为webpack在转译时需要该模块存在。 - Akash Kava

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接