Custom Library Components Does not show required props on intellisense

Custom Library Components Does not show required props on intellisense


I developed a custom React component library to be consume on a private npm. All my components are Typescript React Class Components and in many I used interfaces to declare which props are optional or required. Example:

export interface ICardLinkProps {

    Title: string;
    Description: string;
    ActionText: string;
    DestinationUrl?: string;
    ImageUrl?: string;
    Icon?: string;
    Theme: Theme;

export class CardLink extends React.Component<ICardLinkProps> {
   /// component Code.

All the components work as expected but when my coworkers install de package the intellisense does not show the required props. Example:

No intellinse

In contrast if I consume a component from Material-UI the intellisense shows all required and optional props.

yes Intellinse

Does anyone have an idea on Why I am not getting the intellisense for my components? I'm using rollup to export build the package, this is my configuration:

import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import external from "rollup-plugin-peer-deps-external";
import resolve from "rollup-plugin-node-resolve";
import url from "rollup-plugin-url";
import PeerDepsExternalPlugin from "rollup-plugin-peer-deps-external";

import pkg from "./package.json";

export default {
  input: "src/index.ts",
  output: [
      file: pkg.main,
      format: "cjs",
      exports: "named",
      sourcemap: true
      file: pkg.module,
      format: "es",
      exports: "named",
      sourcemap: true
  plugins: [

      include: ['**/*.ttf', '**/*.png'],
      limit: Infinity
      rollupCommonJSResolveHack: true,
      exclude: "**/__tests__/**",
      clean: true
      include: ["node_modules/**"],
      namedExports: {
        "node_modules/react/react.js": [
        "node_modules/react-dom/index.js": ["render"],
        'node_modules/react-is/index.js': [
        'node_modules/prop-types/index.js': [

Here is my tsconfig.json

  "compilerOptions": {
    "outDir": "dist",
    "module": "esnext",
    "target": "es5",
    "lib": [
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "declaration": true,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "typeRoots": [
  "include": [
  "exclude": [

Here is the dist folder after runing rollup -c:



This is the contents of the CardLink.d.ts

import React from "react";
import { ICardLinkProps } from "./ICardLinkProps";
 * CardLink Component
 * @extends {Component<ICardLinkProps,ICardLinkState>}
export declare const CardLink: React.ComponentType<Pick<Pick<ICardLinkProps, "theme" | "classes"> & Partial<Pick<ICardLinkProps, "Title" | "Description" | "ActionText" | "DestinationUrl" | "ImageUrl" | "Icon" | "Secondary">> & Partial<Pick<{
    Title: string;
    Description: string;
    ActionText: string;
    DestinationUrl: string;
    ImageUrl: string;
    Icon: string;
    Secondary: boolean;
}, never>>, "Title" | "Description" | "ActionText" | "DestinationUrl" | "ImageUrl" | "Icon" | "Secondary"> & import("@material-ui/core").StyledComponentProps<"centeredIcon" | "icon" | "bellowMargin" | "paper" | "paperSecondary" | "iconSecondary" | "container" | "actionsArea">>;

Thanks in advance.


The question does not show the most important things:

  • the import of the component
  • the package.json of the component package
  • the bundle out dir (assume dist)

The first two items would tell you the name of the components package and how that paths are exported as a node module. Specifically the name and exports field from package.json.

I’m assuming the components package uses a barrel file to export them all from some index file since the build uses a bundler. An alternative would be to simply compile with TS and let the consuming package deal with a bundle.

For a bundled components package with output as given from the images you define the types so they can be found during module resolution. You should probably use NodeNext for moduleResolution.


"name": "components",
"main": "dist/index.js",
"module": "dist/",
"types": "dist/index.d.ts",
"exports": {
  ".": {
    "types": "./dist/index.d.ts",
    "import": "./dist/",
    "require": "./dist/index.js",
    "default": "./dist/index.js"
  "./package.json": "./package.json"

This would allow an import like

import { CardLink } from "components"

Where your editor can handle the types resolution via the types field from the package’s corresponding package.json file.

A better approach would be to not bundle but only compile while also producing a ES module and CommonJS build. Ideally you use different file extensions to at least distinguish the CJS types. Also, avoid a barrel file and use subpath exports. This allows for easier tree shaking by consuming packages and the tool ecosystem.

├── components/
│   ├── Foo/
│   │   └── foo.tsx
│   └── Bar/
│       └── bar.tsx
├── package.json
└── tsconfig.json

Now create a dual build somehow without bundling. It’s easy with @knighted/duel and other options.

Now use wildcards in the subpath exports. Same as before but change the exports:

"exports": {
  "./*": {
    "import": {
      "types": "./dist/*.d.ts",
      "default": "./dist/*.js"
    "require": {
      "types": "./dist/*.d.cts",
      "default": "./dist/*.cjs"

Now you can import from a subpath instead of a barrel file.

import { Foo } from "components/Foo"

The types for Foo will be available to your editor through the types field.

© 2024 Dagalaxy. All rights reserved.