emilkowalski / vaul

A drawer component for React.
https://vaul.emilkowal.ski
MIT License
6.02k stars 203 forks source link

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

Closed lucsmachado closed 3 weeks ago

lucsmachado commented 7 months ago

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.

rortan134 commented 4 months ago

Fixed once #348 lands

ryanburns23 commented 4 months ago

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';
ErikLysne commented 1 month ago

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>
};
emilkowalski commented 3 weeks ago

Fixed in #348