Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected Type Definition for class and className #254

Open
carlosyan1807 opened this issue Jan 10, 2024 · 5 comments
Open

Unexpected Type Definition for class and className #254

carlosyan1807 opened this issue Jan 10, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@carlosyan1807
Copy link

Describe the bug

I'm encountering an issue while using the [email protected] library in a monorepo setup with shared style variants for both Next.js and Nuxt.js projects. After using Vite to bundle the shared project, the generated TypeScript declaration file contains confusing type definitions for the class and className properties.

It's my learning project, so it includes both next and nuxt.

To Reproduce

// src/variants/ripple.ts
import type { VariantProps } from 'cva'

import { cva } from 'cva'

const rippleVariants = cva({
  base: ['pointer-events-none absolute origin-center animate-ripple rounded-full opacity-0'],
  variants: {
    color: {
      default: 'bg-current',
      neutral: 'bg-neutral',
      primary: 'bg-primary',
      secondary: 'bg-secondary',
      info: 'bg-info',
      success: 'bg-success',
      warning: 'bg-warning',
      danger: 'bg-danger',
    },
  },
})

export type RippleVariantProps = VariantProps<typeof rippleVariants>

export { rippleVariants }
// dist/variants/ripple.d.ts
import type { VariantProps } from '../../node_modules/cva';
declare const rippleVariants: (props?: ({
    color?: "primary" | "secondary" | "neutral" | "info" | "success" | "warning" | "danger" | "default" | undefined;
} & ({
    class?: string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | any | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined;
    className?: undefined;
} | {
    class?: undefined;
    className?: string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | (string | number | boolean | any | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined)[] | {
        [x: string]: any;
    } | null | undefined;
})) | undefined) => string;
export type RippleVariantProps = VariantProps<typeof rippleVariants>;
export { rippleVariants };

my vite.config.ts

import dts from 'vite-plugin-dts'

export default defineConfig({
  build: {
    outDir: 'dist',
    emptyOutDir: true,
    lib: {
      entry: entries,
      formats: ['es'],
    },
    rollupOptions: {
      external: ['cva']
    }
  },
  plugins: [dts()],
})

Expected behavior
I'm not sure if this is a problem with cva or if I'm doing something wrong, I want it to generate the right type.

Desktop (please complete the following information):

  • OS: Windows 11 WSL2
  • Browser chrome
  • Version 120
@carlosyan1807 carlosyan1807 added the bug Something isn't working label Jan 10, 2024
@joe-bell
Copy link
Owner

Hmm, please can you private a working reproduction? (not code snippets, but a sandbox of some sorts)

@carlosyan1807
Copy link
Author

https://codesandbox.io/p/sandbox/amazing-galois-2d6j7p

cat dist/variants/ripple.d.ts

@danmudd-vox
Copy link

danmudd-vox commented Aug 5, 2024

This appears to be caused by ClassValue and ClassArray being recursive types. As ClassValue isn't exported and referenceable, types for components using VariantTypes attempt to reconstruct the ClassValue type definition for their class and className props - but because they don't have a type to refer to, it keeps recursing and generates a crazy nested type definition for 10+ levels of depth to attempt replicate the ClassArray type.

These types look to be very similar to those in clsx, which gets around it by exporting the types. Exporting ClassValue should be enough to fix this (and fixed it in my replication).

@MrOxMasTer
Copy link

MrOxMasTer commented Oct 22, 2024

Hmm, please can you private a working reproduction? (not code snippets, but a sandbox of some sorts)

I don't see why you would want to create your own ClassValue implementation when you're using clsx under the hood anyway. It gives me problems with a type that doesn't exist for cva

image

bigint does not exist in cva

And there's also a problem with ClassValue[] because it doesn't fit even if I use cx:
image

and don't export the type from the library

@MrOxMasTer
Copy link

added bigint to the clx 2.1.1 version (in April)

https://github.com/lukeed/clsx/releases/tag/v2.1.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants