Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

eosjs in Nodejs with Typescript #833

Closed
isastim opened this issue Feb 12, 2021 · 2 comments
Closed

eosjs in Nodejs with Typescript #833

isastim opened this issue Feb 12, 2021 · 2 comments

Comments

@isastim
Copy link

isastim commented Feb 12, 2021

Version of EOSJS
Snippet of package.json

  "dependencies": {
    "@hapi/hapi": "^20.1.0",
    "@hapi/inert": "^6.0.3",
    "@hapi/vision": "^6.0.1",
    "eosjs": "^21.1.0-29-d765fc3",
    "joi": "^17.3.0",
    "node-fetch": "^2.6.1",
    "nodemon": "^2.0.7"
  },
  "devDependencies": {
    "@types/hapi__hapi": "^20.0.5",
    "@types/hapi__inert": "^5.2.2",
    "@types/hapi__joi": "^17.1.6",
    "@types/hapi__vision": "^5.5.2",
    "@types/node": "^14.14.27",
    "@types/node-fetch": "^2.5.8",
    "@types/text-encoding": "0.0.35",
    "eslint": "^7.18.0",
    "eslint-config-standard": "^16.0.2",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "hapi-swagger": "^14.1.0",
    "typescript": "^4.1.5"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "tsc": "tsc"
  },

My tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["dom", "ES2020"],
    "outDir": "./build",
    "strict": true,
    "esModuleInterop": true,                  
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true  
  }
}

I am running Nodejs version 14.15.5

Describe the bug
As the title describes I am trying to get eosjs working in a Nodejs application with Typescript support. Javascript works fine.
I have not one but two errors. Here is my relevant code snippet:

import { Api, JsonRpc } from "eosjs"
import { JsSignatureProvider } from "eosjs/dist/eosjs-jssig"
import * as fetch from "node-fetch"
import { TextEncoder, TextDecoder } from "util"

let rpc: JsonRpc;
let api: Api;
let signatureProvider: JsSignatureProvider;

exports.connect = ({ privateKey, ip, port }: { privateKey: string, ip: string, port: number }) => {
    signatureProvider = new JsSignatureProvider([privateKey])
    rpc = new JsonRpc(`http://${ip}:${port}`, {fetch}) // 1st Error
    api = new Api({ rpc, signatureProvider, textEncoder: new TextEncoder(), textDecoder: new TextDecoder() }) // 2nd Error
    console.log(JSON.stringify(api, undefined, 1))
    return api
}

I am compiling with npx tsc.
For the first error I get the following message:

functions.ts:25:48 - error TS2322: Type 'typeof import("/home/isastim/cls-box-client/node_modules/@types/node-fetch/index")' is not assignable to type '(input?: any, init?: any) => Promise<any>'.
  Type 'typeof import("/home/isastim/cls-box-client/node_modules/@types/node-fetch/index")' provides no match for the signature '(input?: any, init?: any): Promise<any>'.

25     rpc = new JsonRpc(`http://${ip}:${port}`, {fetch})

For the second error:

functions.ts:26:77 - error TS2322: Type 'import("util").TextDecoder' is not assignable to type 'TextDecoder'.
  Types of property 'decode' are incompatible.
    Type '(input?: Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | ... 7 more ... | undefined, options?: { ...; } | undefined) => string' is not assignable to type '{ (input?: ArrayBuffer | ArrayBufferView | undefined, options?: TextDecodeOptions | undefined): string; (input?: Uint8Array | undefined, options?: TextDecoderOptions | undefined): string; }'.
      Types of parameters 'input' and 'input' are incompatible.
        Type 'ArrayBuffer | ArrayBufferView | undefined' is not assignable to type 'Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | ... 7 more ... | undefined'.
          Type 'ArrayBufferView' is not assignable to type 'Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | ... 7 more ... | undefined'.
            Type 'ArrayBufferView' is missing the following properties from type 'DataView': getFloat32, getFloat64, getInt8, getInt16, and 17 more.

26     api = new Api({ rpc, signatureProvider, textEncoder: new TextEncoder(), textDecoder: new TextDecoder() })
                                                                               ~~~~~~~~~~~

  node_modules/eosjs/dist/eosjs-api.d.ts:46:9
    46         textDecoder?: TextDecoder;
               ~~~~~~~~~~~
    The expected type comes from property 'textDecoder' which is declared here on type '{ rpc: JsonRpc; authorityProvider?: AuthorityProvider | undefined; abiProvider?: AbiProvider | undefined; signatureProvider: SignatureProvider; chainId?: string | undefined; textEncoder?: TextEncoder | undefined; textDecoder?: TextDecoder | undefined; }'


Found 2 errors.

Expected behavior
I've expected that the application would compile without any errors. The Readme didn't give any more info other than installing the typings and adding "dom" to the tsconfig.json.

Desktop (please complete the following information):

  • OS: Ubuntu Desktop 20.04 LTS
  • Browser: none (Nodejs)
@isastim
Copy link
Author

isastim commented Feb 15, 2021

So I got it working now by doing the following:

For the node-fetch error I saw this issue post from some library with the same problem as eosjs. They fixed it by using cross-fetch instead of node-fetch which allegedly should do the same. Just Import import * as crossFetch from "cross-fetch" and use it rpc = new JsonRpc(`http://${ip}:${port}`, crossFetch) .

The second one was tricky since I had to dig a little in the eosjs source code. Inside node_modules/eosjs/dist/eosjs-api.d.ts I noticed that the Api class uses TextEncoder and TextDecoder but nowhere are these types imported. VSCode found the default declarations that are being used are inside /usr/share/code/resources/app/extensions/node_modules/typescript/lib/lib.dom.d.ts which are mismatching with nodejs'. As a quick and dirty solution I've now manually imported nodejs' own declarations inside node_modules/eosjs/dist/eosjs-api.d.ts with import {TextEncoder, TextDecoder} from "util". I'd be glad if someone could come up with a cleaner solution to this.

@isastim
Copy link
Author

isastim commented Feb 16, 2021

Ok, so I found a better solution for the second problem. Typescript brings its own TextEncoder and TextDecoder classes which for my purposes worked as well as Nodejs'. So just simply don't import import { TextDecoder, TextEncoder } from "util" and you should automatically be good to go.

@isastim isastim closed this as completed Feb 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant