【问题标题】:Cannot import 'socket.io-client' as module in typescript无法在打字稿中将“socket.io-client”作为模块导入
【发布时间】:2019-04-12 10:55:44
【问题描述】:

我已经使用 npm 添加了@types/socket.io-client 模块

npm install --save @types/socket.io-client

在我的文件 datapulse.ts 中导入之后

import * as io from 'socket.io-client'
export class DataPulseProvider {
    private socket: any;
    public constructor(socketServer: string) {
       this.socket = io(socketServer);
    }
// do something
}

但是当我构建我的项目时,我遇到了一个错误

[!] Error: Cannot call a namespace ('io')

任何人都有使用 typscript 的 socket.io-client 的经验,请帮我解决上述问题。谢谢!

【问题讨论】:

    标签: typescript socket.io


    【解决方案1】:

    按照socket.io ES6 import 你会这样做:

    import io from 'socket.io-client';
    const socket = io('http://localhost');
    

    简而言之,您必须按照旧方式进行操作:

    import * as io from 'socket.io-client';
    

    不符合 ES6,此外,io 不再可调用(根据 ES^ 命名空间规范,它只能是对象):

    // reports TS error
    io(/* ... */);
    

    所以你必须扩展 tsconfig.json 以便 TS 为你将可调用的 io 包装到一个对象中并使所有内容再次有效:

    {
        "compilerOptions": {
            "esModuleInterop_comment": "Necessary for incompatible modules to import, like socket.io",
            "esModuleInterop": true,
            // ...
        },
    ,
        "allowSyntheticDefaultImports_comment": "cannot be false, as needed for `esModuleInterop` parameter, though we can omit it",
        "allowSyntheticDefaultImports": true,
        // ...
    }
    
    

    这对于命名空间也很有帮助:

    关于esModuleInterop 参数:

    【讨论】:

      【解决方案2】:

      我从未使用过 socket.io-client,但根据 npmjs (https://www.npmjs.com/package/socket.io-client),您必须像这样导入 io

      import io from 'socket.io-client';
      

      它告诉我这个库有一个带有export default 关键字的函数。但是您使用import * as io,这意味着您要导入整个模块——一个包含默认和命名导出成员的对象,并且您希望将此对象称为io

      【讨论】:

      • 谢谢@Yakov Fain,但是@types/socket.io-client 没有export default 的任何功能,所以我不能像你上面那样导入。
      • 他们的 d.ts 文件不使用 ES6 模块 github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/…。我可能老了,与库的实际实现不匹配。试试import io = require("io");
      • 我已经按照您的建议进行了尝试,但出现错误Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.
      • 看起来实际代码和 d.ts 不匹配。只需声明类型为 any 的变量 io 并在没有 IDE 帮助的情况下使用 socket.io-client。
      • 我这样声明var io: any; io = require('socket.io-client');,但又出现了一个错误Uncaught ReferenceError: require is not defined
      【解决方案3】:

      正如 Socket.io 文档所说(现在)不再需要类型模块。卸载它以消除错误。

      TypeScript 用户注意:这些类型现在包含在 socket.io-client 包中,因此不再需要来自 @types/socket.io-client 的类型,实际上可能会导致错误: ~Docs

      正确的导入应该是这样的

      // ES6 import or TypeScript
      import { io } from "socket.io-client";
      // CommonJS 
      const io = require("socket.io-client");
      

      ~Docs client-initialization

      @types/socket.io-client 包给我带来了麻烦,这就是为什么我搜索解决方案并找到另一个 Stack Post 时遇到导入错误的问题

      【讨论】:

        猜你喜欢
        • 2016-05-21
        • 1970-01-01
        • 1970-01-01
        • 2021-08-31
        • 1970-01-01
        • 2012-12-28
        • 1970-01-01
        • 2017-10-29
        • 2019-09-30
        相关资源
        最近更新 更多