vaul icon indicating copy to clipboard operation
vaul copied to clipboard

TS4023: Exported variable 'Drawer' has or is using name 'WithFadeFromProps' from external module but cannot be named.

Open lucsmachado opened this issue 1 year ago • 2 comments

Hi there! Sorry if this has already been asked and answered, but I couldn't find any references to this particular error on the issues page.

I'm trying to re-export the components, like so:

import { Drawer as DrawerPrimitive } from "vaul";

export const Drawer = {
  Root: DrawerPrimitive.Root,
};

But I get the following error:

Diagnostics:

  1. Exported variable 'Drawer' has or is using name 'WithFadeFromProps' from external module "<cwd>/node_modules/vaul/dist/index" but cannot be named. [4023]
  2. Exported variable 'Drawer' has or is using name 'WithoutFadeFromProps' from external module "<cwd>/node_modules/vaul/dist/index" but cannot be named. [4023]

A quick search lead me to this Stack Overflow answer, so I tried "Option 1" by importing it like so:

import { Drawer as DrawerPrimitive } from "../../../../../node_modules/vaul/dist/index";

export const Drawer = {
  Root: DrawerPrimitive.Root,
};

But still the error persists.

"Option 2" does prevent the TypeScript error from popping up, however I'd like to keep type information, so I discarted this as a solution.

import { Drawer as DrawerPrimitive } from "vaul";

export const Drawer = {
  Root: DrawerPrimitive.Root,
} as any; // No errors :) but no types :(

Which leads to "Option 3", which I tried to implement like this:

import { Drawer as DrawerPrimitive } from "vaul";

export const Drawer = {
  Root: DrawerPrimitive.Root as typeof DrawerPrimitive.Root,
};

But the error persists.

Would really appreciate some help in this, as I'm not very well versed in how index.d.ts files work.

lucsmachado avatar Feb 14 '24 19:02 lucsmachado

Fixed once #348 lands

rortan134 avatar May 22 '24 22:05 rortan134

Workaround is to do something like this:

const DrawerNested = ({
  shouldScaleBackground = true,
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.NestedRoot>) => (
  <DrawerPrimitive.NestedRoot
    shouldScaleBackground={shouldScaleBackground}
    {...props}
  />
);
Drawer.displayName = 'DrawerNested';

ryanburns23 avatar May 28 '24 21:05 ryanburns23

When you export DrawerPrimitive.Root its type is implicit, so you need to give it an explicit type. Unfortunately, the DialogProps used by the DrawerPrimitive.Root component in Vaul is not directly accessible.

Luckily, the DialogProps is a pretty simple type, so until it is fixed, a workaround is to shamelessly copy it from the source code into your own file like so:

import { Drawer as DrawerPrimitive } from "vaul";

interface WithFadeFromProps {
  snapPoints: (number | string)[];
  fadeFromIndex: number;
}

interface WithoutFadeFromProps {
  snapPoints?: (number | string)[];
  fadeFromIndex?: never;
}

type DialogProps = {
  activeSnapPoint?: number | string | null;
  setActiveSnapPoint?: (snapPoint: number | string | null) => void;
  children?: React.ReactNode;
  open?: boolean;
  closeThreshold?: number;
  noBodyStyles?: boolean;
  onOpenChange?: (open: boolean) => void;
  shouldScaleBackground?: boolean;
  setBackgroundColorOnScale?: boolean;
  scrollLockTimeout?: number;
  fixed?: boolean;
  dismissible?: boolean;
  handleOnly?: boolean;
  onDrag?: (event: React.PointerEvent<HTMLDivElement>, percentageDragged: number) => void;
  onRelease?: (event: React.PointerEvent<HTMLDivElement>, open: boolean) => void;
  modal?: boolean;
  nested?: boolean;
  onClose?: () => void;
  direction?: 'top' | 'bottom' | 'left' | 'right';
  preventScrollRestoration?: boolean;
  disablePreventScroll?: boolean;
} & (WithFadeFromProps | WithoutFadeFromProps);

export const Drawer = {
  Root: DrawerPrimitive.Root as React.ComponentType<DialogProps>
};

ErikLysne avatar Aug 16 '24 22:08 ErikLysne

Fixed in #348

emilkowalski avatar Sep 07 '24 10:09 emilkowalski