无法使用自定义的Typescript .d.ts文件

时间:2015-10-29 13:44:48

标签: typescript

我正在学习打字稿,当我尝试在打字稿定义文件中定义此类时,我遇到了问题,然后在打字稿文件中使用它。

我有一个javascript" class"这是" Facade" (众所周知的设计模式)OpenLayers库。这个立面是这样的:

lib / carto-facade / OpenLayerFacade.js:

function OpenLayerFacade() {
    this.map =   new ol.Map({
        layers: [
            new ol.layer.Tile({source: new ol.source.OSM()})
        ],
        view: new ol.View({
            center: [43.5, 5.0],
            zoom: 2
        }),
        target: 'map'
    });
}

OpenLayerFacade.prototype.setViewCenter = function(latitude, longitude)  {
    this.map.getView().setCenter(ol.proj.fromLonLat([longitude, latitude]));
}

然后,我希望能够在打字稿项目中使用这个外观。所以我写了我的.d.ts文件如下:

LIB / CARTO-门面/ OpenLayerFacade.d.ts

declare interface OpenLayerfacade {
    setViewCenter(latitude:number, longitude:number):void;
}

declare interface OpenLayerfacadeFactory {
    new(divName:string): OpenLayerfacade;
}

export var OpenLayerfacade:OpenLayerfacadeFactory;

现在我想在浏览器加载的TS脚本中使用它:

/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../lib/carto-facade/OpenLayerFacade.d.ts" />

import oli = require('../lib/carto-facade/OpenLayerFacade');

$(document).ready(function () {
    var ol = new oli.OpenLayerFacade("map");
    ol.setViewCenter(43.5, 6.0);
    console.log("Map displayed");
});

Everythings编译(oups,tranpile)很好,但是当我加载包含脚本的网页时,我有以下错误:

未捕获的TypeError:无法读取属性&#39; OpenLayerFacade&#39;未定义的

当我尝试实例化一个新的&#34; OpenLayerFacade&#34;时会发生这种情况。

我正在使用require.js,所以我使用选项&#34;模块&#34;:&#34; amd&#34;在我的tsconfig.json

我的HTML文件是:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="/bower_components/jquery/dist/jquery.min.js"></script>
    <script src="/node_modules/openlayers/dist/ol.js"></script>
    <script src="/lib/carto-facade/OpenLayerFacade.js"></script>
    <script data-main="/test_ts/cartotester" src="/bower_components/requirejs/require.js"></script>
</head>
<body>
<div id="map" style="width: 75%; height: 400px"></div>
</body>
<input type="number" id="latitude" placeholder="43.5000"><br>
<input type="number" id="longitude" placeholder="5.5000"><br>
</html>

我做错了什么?

我确信我的问题的答案就在Typescript Handbook的某个地方,但如果有人可以帮我找到,我真的很感激。

此致

2 个答案:

答案 0 :(得分:1)

此代码:

import oli = require('../lib/carto-facade/OpenLayerFacade');

表示您正在导入外部模块。但是您的JS代码不是外部模块(如果需要,您可以在纯JS中编写)。简单的解决方案应该只是省略TS代码中的那一行。然后,您必须确保JS代码在运行时创建全局变量OpenLayerfacade(在d.ts中声明) - 您负责加载JS代码。然后在TS中使用声明的全局变量。

/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../lib/carto-facade/OpenLayerFacade.d.ts" />

$(document).ready(function () {
    var ol = new OpenLayerFacade("map");
    ol.setViewCenter(43.5, 6.0);
    console.log("Map displayed");
});

如果没有commonjs,那将是如何做到的 - 作为内部模块又名namespaces

如果你正在使用commonjs - 并且想要使用外部模块 - 那么你的JS代码必须是commonjs模块(根据TypeScript的外部模块)。此外,您的声明文件必须包含在模块中以指示编译器。

export modules 'oli' {
    declare interface OpenLayerfacade {
        setViewCenter(latitude:number, longitude:number):void;
    }

    declare interface OpenLayerfacadeFactory {
         new(divName:string): OpenLayerfacade;
     }

    export var OpenLayerfacade:OpenLayerfacadeFactory;
}

并以commonjs方式导入:

import oli = require('oli');

你还需要

/// <reference path="../lib/carto-facade/OpenLayerFacade.d.ts" />

告诉编译器在哪里搜索'oli'模块(可以用tsc&gt; 1.6进行简化)。

如果你的JS片段是准确的并且你不想或不能将JS更改为commonjs模块,你仍然可以使用commonjs在你的应用程序中混合它。只需使用名称空间的第一个描述方法。

答案 1 :(得分:1)

使用commonjs时,需要环境外部模块定义。查看此文档:http://www.typescriptlang.org/Handbook#writing-dts-files(§环境外部模块)

有一种方法可以创建适用于内部模块和外部模块的定义。有些东西(我个人原本会描述一个类)

//Internal module
declare namespace Oli {
    class OpenLayerfacade {
        constructor(divName:string);
        setViewCenter(latitude:number, longitude:number):void;
    }
}

//External module
declare module "oli" {
    export = Oli
}

然后导入(新的1.6语法)

import { OpenLayerfacade } from 'oli'