PeerJS具有类型定义,但它们不会作为模块导出。它们是某些命名空间下的类型声明。
我得到:[ts] File 'c:/Users/Vincas/Desktop/language-exchange/node_modules/@types/peerjs/index.d.ts' is not a module.
尝试导入时:import Peer from 'peerjs'
这会尝试从类型定义而不是模块本身导入,如何从模块导入?
来自DefinitelyTyped的文件位于:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/354cec620daccfa0ad167ba046651fb5fef69e8a/types/peerjs/index.d.ts
我已经在这个时候工作了这个:
const PeerJS: typeof Peer = require('peerjs')
const peerjs = new PeerJS({ key: '**********' })
但这远不如:import * as Peer from 'peerjs
或类似的东西......有没有办法避免定义全局函数和全局命名空间?这对我来说只是一种可怕的做法。
答案 0 :(得分:3)
包@types/peerjs
中的已注册类型声明被指定为全局变量。也就是说,它们表明存在名称空间PeerJs
和变量Peer
作为全局声明(也称为“环境”)。
declare var Peer: {
// ...
}
这表明它们应该与可分发的库文件"dist/peer.js"一起使用,而不是与模块一起使用。如果要将此文件直接包含在页面中,编译器应该能够知道这些全局变量是可用的。
但实际上,您想要使用该模块。不幸的是,相同的声明不兼容,必须重新编写以保证一致性。存储库中的旧问题保持打开状态(#176),您似乎不久前创建了#386。你的直觉似乎是正确的:理想情况下,有人必须适应这些
声明。在这种情况下,由于从库中导出的对象是一个类,我们应该遵循class module模式。而不是declare var Peer
,我们可以这样:
export = Peer;
declare class Peer {
constructor(id: string, options?: Peer.PeerJSOption);
constructor(options: Peer.PeerJSOption);
// remaining methods here ...
};
declare namespace Peer {
export interface PeerJSOption {
// ...
}
// ...
}
其他接口类型放在具有相同名称的命名空间内,以便正确导出所有内容。
我亲自接过任务:在"index.d.ts"中,新文件this branch被添加到存储库中,还有一些额外的package.json字段。这使得声明仅通过安装主依赖项就可以工作,不需要其他包(特别是,你不应该添加“@ types / peerjs”)。
您甚至可以自己尝试一下:
的package.json:
{
"name": "test-peerjs-ts",
"version": "0.1.0",
"main": "index.ts",
"dependencies": {
"peerjs": "git+https://github.com/Enet4/peerjs.git#typescript-types"
}
}
index.ts:
import Peer = require('peerjs');
let peer = new Peer("id");
let peer2 = new Peer("id", {});
type DataConn = Peer.DataConnection;
您可能只会看到来自webrtc
类型的一堆TypeScript错误,这些错误显然包含最新TypeScript编译器中已有的定义。仍然,编译过程将成功运行并产生良好的JavaScript代码:
"use strict";
exports.__esModule = true;
var Peer = require("peerjs");
var peer = new Peer("id");
var peer2 = new Peer("id", {});