1

I have added @types/socket.io-client module using npm

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

After that import in my file datapulse.ts like that

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

But when I build my project I got an error

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

Anyone have some experience with socket.io-client with typscript, please help me resolve above issue. Thank you!

hungnm10
  • 21
  • 2
  • 7

3 Answers3

2

Following the socket.io ES6 import you would do:

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

In short, you have to do it as the old way:

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

is not compliant with ES6 and in the addition io is not callable anymore (it can be only object according to the ES^ namespacing specification):

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

So you have to extend tsconfig.json so TS will wrap for you the callable io into an object and make everything valid again:

{
    "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,
    // ...
}

This can also be helpful regarding namespacing:

And this regarding the esModuleInterop parameter:

mPrinC
  • 9,147
  • 2
  • 32
  • 31
0

I never worked with socket.io-client, but as per npmjs (https://www.npmjs.com/package/socket.io-client), you have to import io like this:

import io from 'socket.io-client';

It tells me that this library has one function with the export default keywords. But you use import * as io, which means that you want to import the entire module - an object that includes the default and named exported members, and you want to refer to this object as io.

Yakov Fain
  • 11,972
  • 5
  • 33
  • 38
  • Thanks @Yakov Fain, but @types/socket.io-client does not has any functions with `export default` so I cannot import like you above. – hungnm10 Apr 12 '19 at 18:40
  • Their d.ts file doesn't use ES6 modules https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/socket.io-client/index.d.ts. I may be old and doesn't match the actual implementation of the library. Try ```import io = require("io");``` – Yakov Fain Apr 13 '19 at 13:48
  • I've tried as your suggestion but it got an error `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.` – hungnm10 Apr 13 '19 at 18:30
  • Looks like a mismatch between the actual code and d.ts. Just declare the variable io of type any and use socket.io-client without IDE help. – Yakov Fain Apr 14 '19 at 01:43
  • I declared like that `var io: any; io = require('socket.io-client');` but it got another error `Uncaught ReferenceError: require is not defined` – hungnm10 Apr 16 '19 at 07:50
0

As the Socket.io Documentation says (nowadays) the types module isn't needed anymore. Uninstall it to get rid of the error.

Note for TypeScript users: the types are now included in the socket.io-client package and thus the types from @types/socket.io-client are not needed anymore and may in fact cause errors: ~ Docs

A correct import would look like this

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

~ Docs client-initialization

the @types/socket.io-client package was causing me troubles that's why I searcht for a solution and found another Stack Post where they had trouble with errors on the import