neo4j / neo4j-javascript-driver

Neo4j Bolt driver for JavaScript
https://neo4j.com/docs/javascript-manual/current/
Apache License 2.0
860 stars 147 forks source link

Typescript TS2742 error when upgrading 4.X.X to 5.4.0 #1053

Open AGallouin opened 1 year ago

AGallouin commented 1 year ago

Hello,

When bumping neo4j-driver package from 4.4.2 to 5.4.0, I'm having issues with the base types of neo4j (Integer, Record, Session etc.). All my neo4j connections are made using a facade package around neo4j-driver, and exposing basic methods and aliases to the types mentioned above to the rest of the codebase. Everytime typescript needs to infer a return type that includes one of thoses types, I have an error like this one.

(!) Plugin typescript: @rollup/plugin-typescript : The inferred type of 'int' cannot be named without a reference to 'neo4j-driver/node_modules/neo4j-driver-core/types/integer'. This is likely not portable. A type annotation is necessary.

The only simple solution i found until now is to add directly the package neo4j-driver-core as a dependency of my package even though the readme explicitly tells me otherwise.

Dependency schema if unclear:

Codebase ==> My neo4j driver package Wrapper ==> neo4j-driver ==> neo4j-driver-core
             ^ Exposes some methods with         ^ exposes
             base neo4j-driver base types        underlying
                                                 neo4j-driver-core
                                                 types

I don't even understand why does this error means exactly, do you have any insights on it ?

bigmontz commented 1 year ago

Hey @AGallouin, how do the package is being imported? which typescript version are you using? Could you check if you have the same issue with 5.3.0?

bigmontz commented 1 year ago

Issue closed due inactivity. Please, open again the issue if the error persists and you have more evidences.

dylanjt commented 1 year ago

@bigmontz what timing haha - I am looking at this issue right now as I am also facing this error.

dylanjt commented 1 year ago

@bigmontz for me I've reproduced the issue on 5.14, 5.13, and 5.3.0 since it's mentioned above. I am using typescript@5.2.2 in a pnpm workspace. My usage is like so:

// neo4j.ts
import neo4j from "neo4j-driver";

const { NEO4J_URI, NEO4J_AUTH_USERNAME, NEO4J_AUTH_PASSWORD } = process.env;

if (!NEO4J_URI || !NEO4J_AUTH_USERNAME || !NEO4J_AUTH_PASSWORD) {
  throw Error("Missing Neo4j environment variables");
}

export default neo4j.driver(
  NEO4J_URI,
  neo4j.auth.basic(NEO4J_AUTH_USERNAME, NEO4J_AUTH_PASSWORD)
);

// index.ts
import neo4j from "./neo4j";
import { Draft, Node, Relationship } from "./types";

export default neo4j;

export async function create<T extends keyof Node>(
  label: T,
  properties: Draft<Node[T]>
) {
  const session = neo4j.session();
  const res = await session.run<Node[T]>(
    `...Cypher query...`,
    { label, ...properties }
  );

  return res;
}

The declaration of the create function triggers the following error:

The inferred type of 'create' cannot be named without a reference to '.pnpm/neo4j-driver-core@5.14.0/node_modules/neo4j-driver-core/types/result'. This is likely not portable. A type annotation is necessary.
dylanjt commented 1 year ago

For anyone in need of an interim solution: it's regrettable, but explicitly installing neo4j-driver-core and adding the following import resolves the issue for me:

import "neo4j-driver-core";
bigmontz commented 1 year ago

Can you share your tsconfig file?

bigmontz commented 1 year ago

I had configured a project like this, npm run build works fine.

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES5",
    "lib": ["ES6", "es2015"],
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
    "moduleResolution": "node",
    "downlevelIteration": true,
    "outDir": "lib",
    "declaration": true,
    "declarationDir": "types",
    "isolatedModules": true,
    "types": ["node"]
  },
  "include": [
    "index.ts"
  ]
}
// package.json
{
  "name": "github1053",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "tsc -p tsconfig.json"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "neo4j-driver": "^5.14.0"
  },
  "devDependencies": {
    "@types/node": "^20.8.9",
    "typescript": "^5.2.2"
  }
}
// index.ts
import { RecordShape } from "neo4j-driver";
import neo4j from "./neo4j";

export default neo4j;

export async function create<Shape extends RecordShape = RecordShape>(
  label: string,
  properties: any
) {
  const session = neo4j.session();
  const res = await session.run<Shape>(
    `...Cypher query...`,
    { label, ...properties }
  );

  return res;
}
// neo4j.ts

import neo4j from "neo4j-driver";

// @ts-ignore
const { NEO4J_URI, NEO4J_AUTH_USERNAME, NEO4J_AUTH_PASSWORD } = process.env;

if (!NEO4J_URI || !NEO4J_AUTH_USERNAME || !NEO4J_AUTH_PASSWORD) {
  throw Error("Missing Neo4j environment variables");
}

export default neo4j.driver(
  NEO4J_URI,
  neo4j.auth.basic(NEO4J_AUTH_USERNAME, NEO4J_AUTH_PASSWORD)
);
bigmontz commented 10 months ago

@dylanjt Can you share your tsconfig?