#Shared ts lib with project references; exported types conflicts and even resolve to any at times

6 messages · Page 1 of 1 (latest)

buoyant ibex
#

I have built a react app with typescript and decided to move some code into a separate npm package using typescript references for easy builts. The moved code is mostly related to interacting with a 3rd party lib called Slate. (text editor written in react and typescript)
The separation here only moves the data core but not anything react related. So the shared lib is a simple typescript package with basically one main dependency being Slate. Later I want to be able to use this package in the backend as well as the frontend.

After having moved the code i start to see a few weird type conflicts. I already tried to install Slate in the shared package as peer dependency but that doesnt seem to have an effect on the "tsc --build".

Consumer (react app)

.d.ts file to augment 3rd party lib 'Slate'

import { Element, EventsEditor, TextNode } from 'law-document';
import { BaseEditor } from 'slate';
import { ReactEditor } from 'slate-react';

declare module 'slate' {
    interface CustomTypes {
        Editor: BaseEditor & EventsEditor & ReactEditor
        Element: Element;
        Text: TextNode;
    }
}

#

Calling shared lib function "findListItemAtSelection"

import { findListItemAtSelection, isAtEdgeOf, isWithoutMarks } from 'law-document';
import { Editor } from 'slate';

const showNameFormatButton = (editor: Editor) => {
    const [, listItemPath] = findListItemAtSelection(editor) ?? [];
    if (!listItemPath) {
        return false;
    }

    if (
        isAtEdgeOf(editor, 'title', 'end', listItemPath)
        || isAtEdgeOf(editor, 'sentence', 'start', listItemPath)
        || isWithoutMarks(editor)
    ) {
        return true;
    }

    return false;
};

export default showNameFormatButton;

#

results in the error: (Problem 1)

Argument of type 'BaseEditor & EventsEditor & ReactEditor' is not assignable to parameter of type 'BaseEditor & EventsEditor & HistoryEditor'.
  Type 'BaseEditor & EventsEditor & ReactEditor' is not assignable to type 'BaseEditor'.
    Types of property 'operations' are incompatible.
      Type 'import("/client/node_modules/slate/dist/interfaces/operation").BaseOperation[]' is not assignable to type 'import("/law-document/node_modules/slate/dist/interfaces/operation").BaseOperation[]'.
        Type 'import("/client/node_modules/slate/dist/interfaces/operation").BaseOperation' is not assignable to type 'import("/law-document/node_modules/slate/dist/interfaces/operation").BaseOperation'.
          Type 'BaseInsertNodeOperation' is not assignable to type 'BaseOperation'.
            Type 'import("/client/node_modules/slate/dist/interfaces/operation").BaseInsertNodeOperation' is not assignable to type 'import("/law-document/node_modules/slate/dist/interfaces/operation").BaseInsertNodeOperation'.
              Types of property 'node' are incompatible.
                Type 'import("/client/node_modules/slate/dist/interfaces/node").Node' is not assignable to type 'import("/law-document/node_modules/slate/dist/interfaces/node").Node'.
                  Type 'BaseEditor & EventsEditor & ReactEditor' is not assignable to type 'Node'.ts(2345)
#

Problem 2: Importing HistoryEditor from slate-history

// import { YjsEditor } from '@slate-yjs/core';
import { Element, EventsEditor, TextNode } from 'law-document';
import { BaseEditor } from 'slate';
import { HistoryEditor } from 'slate-history';
import { ReactEditor } from 'slate-react';

declare module 'slate' {
    interface CustomTypes {
        Editor: BaseEditor & EventsEditor /* & YjsEditor */ & ReactEditor & HistoryEditor;
        Element: Element;
        Text: TextNode;
    }
}

gives this eslint error:

'any' overrides all other types in this intersection type.eslint@typescript-eslint/no-redundant-type-constituents

Important note: all this code and dependencies were working fine before splitting lib code into a separate package. It seems to be a pure types issue the way the ts projects are setup right now.

#

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "lib": [
            "dom",
            "dom.iterable",
            "esnext"
        ],
        "incremental": true,
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noFallthroughCasesInSwitch": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "downlevelIteration": true,
        "jsx": "react-jsx",
        "rootDir": "./src"
    },
    "references": [{
        "path": "../client-sdk"
    }, {
        "path": "../law-document"
    }],
    "include": [
        "src"
    ],
    "exclude": [
        "node_modules",
    ]
}
#

Shared Lib

import { Editor, BaseEditor } from 'slate';

export const findListItemAtSelection = (editor: Editor, tag?: MetaType): ...

declare module 'slate' {
    interface CustomTypes {
        Editor: BaseEditor & EventsEditor & HistoryEditor;
        Element: Element;
        Text: TextNode;
    }
}

export type Element = List | ListItem | ListItemText | DocumentMetaElement | Paragraph;

//tsconfig.json
{
  "compilerOptions": {
    "incremental": true,
    "composite": true,
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "module": "commonjs",
    "rootDir": "./src",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "outDir": "./dist",
    "downlevelIteration": true,
    "isolatedModules": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

The shared lib is installed via npm i ../law-document