English 中文(简体)
与推广者(NextUI)建立习俗成分,没有打字
原标题:Creating custom component with extendVariants(NextUI) fails with typescript extraction

试图通过扩大“未来倡议”的某些组成部分而形成一个组成部分。

I wanted to start simple by doing the classic button. But unfortuantly I got stuck... when I build the npm package I get this:

stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  ../../../node_modules/.pnpm/registry.npmjs.org+@[email protected]_@[email protected][email protected][email protected]/node_modules/@nextui-org/system-rsc/dist/types . This is likely not portable. A type annotation is necessary.      
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  ../../../node_modules/.pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@nextui-org/react-utils/dist/refs . This is likely not portable. A type annotation is necessary.
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  .pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@react-types/shared . This is likely not portable. A type annotation is necessary.
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  .pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@react-types/shared . This is likely not portable. A type annotation is necessary.
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  .pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@react-types/shared . This is likely not portable. A type annotation is necessary.
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  .pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@react-types/shared . This is likely not portable. A type annotation is necessary.
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  .pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@react-types/shared . This is likely not portable. A type annotation is necessary.
stories/components/Button/Button.tsx(55,7): error TS2742: The inferred type of  MyButton  cannot be named without a reference to  .pnpm/registry.npmjs.org+@[email protected][email protected]/node_modules/@react-types/shared . This is likely not portable. A type annotation is necessary.

由于这一错误,在使用时,单板就失去其类型安全。

也许我会做一些错误的事情。 首先,我收到了,即,(也给出错误)。

Then I added my own variants to the button to test, the end result is this:

import { extendVariants, Button as NextUiButton } from  @nextui-org/react ;
import { ReactNode, Ref } from  react ;
import { type VariantProps } from  tailwind-variants ;

const MyButton = extendVariants(NextUiButton, {
    variants: {
        // <- modify/add variants
        color: {
            primary:  bg-blue-500 text-black ,
            secondary:  bg-purple-500 text-black ,
        },
        isDisabled: {
            true:  bg-[#eaeaea] text-[#000] opacity-50 cursor-not-allowed ,
        },
        size: {
            xs:  px-unit-2 min-w-unit-12 h-unit-6 text-tiny gap-unit-1 rounded-small ,
            md:  px-unit-4 min-w-unit-20 h-unit-10 text-small gap-unit-2 rounded-small ,
            xl:  px-unit-8 min-w-unit-28 h-unit-14 text-large gap-unit-4 rounded-medium ,
        },
    },
    defaultVariants: {
        // <- modify/add default variants
        color:  primary ,
        size:  xl ,
    },
    compoundVariants: [
        // <- modify/add compound variants
        {
            isDisabled: true,
            color:  secondary ,
            class:  bg-[#84cc16]/80 opacity-100 ,
        },
    ],
});
interface MyButtonProps extends VariantProps<typeof MyButton> {
    ref?: Ref<HTMLButtonElement>;
    className?: string;
    children?: ReactNode;
    label: string;
}

export const Button = ({ size, className, color, label, children, ref }: MyButtonProps) => {
    return (
        <MyButton
            {...{
                ref,
                className,
                size,
                color,
                type:  button ,
            }}>
            {children}
            {label}
        </MyButton>
    );
};

但是,对建筑步骤中的类型进行抽取,造成上述错误。

V:

import {defineConfig} from  vite 
import react from  @vitejs/plugin-react 
import dts from  vite-plugin-dts 
import {libInjectCss} from  vite-plugin-lib-inject-css 
import {extname,relative,resolve} from  path 
import {fileURLToPath} from  node:url 
import {glob} from  glob 

export default defineConfig({
  plugins: [react(),libInjectCss(),dts({include: [ stories/components ]})],
  build: {
    copyPublicDir: false,
    lib: {
      entry: resolve(__dirname, stories/main.ts ),
      formats: [ es ],
      name: "my-components",
    },
    rollupOptions: {
      external: [ react , react/jsx-runtime ,"tailwind-variants","framer-motion",RegExp("^(@nextui-org/).+")],
      input: Object.fromEntries(
        glob.sync( stories/**/*.{ts,tsx,js,jsx} ,{ignore:  stories/**/*.stories.{ts,tsx,js,jsx} }).map(file => [
          relative(
             stories ,
            file.slice(0,file.length-extname(file).length)
          ),
          fileURLToPath(new URL(file,import.meta.url))
        ])
      ),
      output: {
        assetFileNames:  assets/[name][extname] ,
        entryFileNames:  [name].js ,
      }
    },
  },
})

作为副注,如果我使用尾气var制造自己的纽子,所有东西都会奏效,我就在部件上打耳,没有错误。

import { ReactNode, Ref } from  react ;
import { tv, type VariantProps } from  tailwind-variants ;

const button = tv({
    base:  font-medium bg-blue-500 text-white rounded-full active:opacity-80 ,
    variants: {
        color: {
            primary:  bg-blue-500 text-white ,
            secondary:  bg-purple-500 text-white ,
        },
        size: {
            sm:  text-sm ,
            md:  text-base ,
            lg:  px-4 py-3 text-lg ,
        },
    },
    compoundVariants: [
        {
            size: [ sm ,  md ],
            class:  px-3 py-1 ,
        },
    ],
    defaultVariants: {
        size:  md ,
        color:  primary ,
    },
});

interface ButtonProps extends VariantProps<typeof button> {
    ref?: Ref<HTMLButtonElement>;
    className?: string;
    children?: ReactNode;
    label: string;
}

export const Button = ({ size, className, color, label, children, ref }: ButtonProps) => {
    return (
        <button
            {...{
                ref,
                type:  button ,
                title: label,
                className: button({ className, color, size }),
            }}>
            {children}
            {label}
        </button>
    );
};

Edit: enter image description here

enter image description here

“entergraph

EditTwo: I have created a sandbox to show the issue. Run pnpm build-sb to create the component lib and get the error. And pnpm sb just to start it, which work.

问题回答

首先,如果与:nextui-org/nextui issue 1328 有关:

<代码>pnpm 安装-hoist而不是pnpm 安装

如果不是的话,你至少需要处理文本正遇到的那种推论问题。 形形形形形形形形色色,难以为你的扩展部分推论。 通过明确界定这些类型,你将提供明确信息,说明预期的是什么样子:

import { extendVariants, Button as NextUiButton, ButtonProps as NextUiButtonProps } from  @nextui-org/react ;
import { ReactNode, Ref } from  react ;
import { type VariantProps } from  tailwind-variants ;

// Explicitly define the type for MyButtonProps
interface MyButtonProps extends VariantProps<typeof MyButton>, NextUiButtonProps {
    ref?: Ref<HTMLButtonElement>;
    className?: string;
    children?: ReactNode;
    label: string;
}

// Your existing MyButton implementation
const MyButton = extendVariants(NextUiButton, {
    // variants configuration
});

// Use the explicitly defined MyButtonProps
export const Button = (props: MyButtonProps) => {
    return <MyButton {...props} />;
};

我曾尝试过上述情况。 我删除了Node_modules和pnpm-lock,然后删除了pnpm i-hoist。 但错误仍然存在......没有改变: 这是多余的。

页: 1 此外,还试图仅使用<代码>npm。

stories/components/Button/Button.tsx(107,7): error TS2742: The inferred type of  WtButton  cannot be named without a reference to  ../../../node_modules/@nextui-org/system-rsc/dist/types . This is likely not portable. A type annotation is necessary. 
stories/components/Button/Button.tsx(107,7): error TS2742: The inferred type of  WtButton  cannot be named without a reference to  ../../../node_modules/@nextui-org/react-utils/dist/refs . This is likely not portable. A type annotation is necessary

由于即使在尝试诸如<代码>pnpm 安装——hoist和改用npm等解决办法之后,这些错误依然存在,这个问题可能深深地植根于对你的扩展组成部分的处理类型。

既然问题涉及从下游企业部件中提炼的类型,如果出口,从下游企业内部模块直接进口这些类型可能会有所帮助。 这是一条工作轨道,取决于“下一个倡议”一揽子方案的内部结构(......这可能会改变今后的更新,有可能破坏你们的执行)。

// Import types directly from NextUI s internal modules
import { ButtonProps as NextUiButtonProps } from  @nextui-org/system-rsc/dist/types ;
import { RefProps } from  @nextui-org/react-utils/dist/refs ;

// Define your extended button props using these imported types
interface MyButtonProps extends NextUiButtonProps, RefProps {
  // Your additional props
}

另一种替代做法是绕航类型与any

虽然这在保持类型安全方面并不理想,但作为最后的手段,你可以绕过使用<条码>的任何<<>条/代码>对具体案例的字体检查。 这是为了测试,因为它否定了字典类型系统的好处。

import { extendVariants, Button as NextUiButton } from  @nextui-org/react ;

// Using  any  to bypass type inference issues
const MyButton: any = extendVariants(NextUiButton, {
  // Your variants configuration
});

// You can still define props for your custom component
interface MyButtonProps {
  // Your props
}

export const Button = (props: MyButtonProps) => {
  return <MyButton {...props} />;
};

不幸的是,在接下来的时间里存在一些问题。 UI refs 和: 任何的解决方案在使用该部件时不会给mu备选案文以正确的类型表示。 同<代码>color:“建议”。

a `import{Reactref,signRef, merRefs } from @nextui-org/react utils/dist/refs ;start:

 Cannot find module  anextui-org/react-utils/dist/refs  or its corresponding type declarations. ts(2307)

鉴于在获取内部类型“下一个倡议”方面继续面临挑战,以及使用<代码> 任何<<<>>>>/代码”的限制,你可能需要探讨一些替代方法:

One way to handle this is to declare a custom type that matches the expected structure of your extended component. That approach involves creating an interface that mirrors the props of the NextUI Button and then adding your custom props.

import { Button as NextUiButton } from  @nextui-org/react ;

// Declare a custom type that extends the inferred props of NextUiButton
interface CustomButtonProps extends React.ComponentProps<typeof NextUiButton> {
  // Add any additional props specific to your variant here
  color?:  primary  |  secondary  |  suggestions ; // example
  // other custom props
}

const MyButton = extendVariants(NextUiButton, {
  // variants configuration
});

export const Button = (props: CustomButtonProps) => {
  return <MyButton {...props} />;
};

另一种做法是使下调系统<代码>Button部分与你的额外功能相匹配,并加以重建。 这种方法可能更为复杂,但可以更多地控制部件的行为和类型处理。

import { Button as NextUiButton } from  @nextui-org/react ;
import React from  react ;

const MyButton = React.forwardRef<HTMLButtonElement, CustomButtonProps>((props, ref) => {
  // Rebuild the button with your custom logic and props
  // Use the NextUiButton as a base and add your customizations
  return <NextUiButton ref={ref} {...props} />;
});

// Define your custom props as needed
interface CustomButtonProps {
  // your custom props and types
}

The OP reference microsoft/Typegust issue 42873

That issue does describe a similar problem where TypeScript fails to correctly infer types across different packages: when a package B depends on package A, and B exports a value with a type defined or referenced by A, TypeScript may produce an error similar to the one you are encountering.
That issue matches your situation, where you are extending a component from NextUI and encountering type inference problems.

议题讨论提出的一项建议包括:确定<条码>声明”的工作:虚假和<条码> 声明Map:虚假,载于<条码>.conftsig.json。 然而,这一解决办法可能并不理想,因为它使发表宣言的卷宗的产生失去意义,而这种文件对于在使用你的图书馆的其他项目中进行文字验证至关重要。

在等待决议时,您不妨考虑简化其组成部分的延伸,并限制使用复杂类型的推论或非专利。 此外,考虑采用不需要以这种复杂方式从第三方图书馆扩展部分的替代图书馆或设计模式。

注: 议题comment 参考:

在图书馆或项目入口处进口成套材料,解决了我的问题。

而且:

我的pm monrepo在申请中进口一揽子物品时,在座标上打错了声明和声明地图。

"declaration": false,
"declarationMap": false,

I have components build upon using only tailwind-variants.
But the nextUI lib have many great things built in like a11y for all its components and great small animations. Would be great to just extendet it.

十二. 下一步工作 用于利用自己内在的无障碍环境(a11y)特征和图像的构造的确是一个好的想法。 既然它涉及的是字典(因为有推论问题),那么你就可以在自己的习俗中加以利用(继承问题)。 这样,你就可以利用“未来倡议”的特征(如-a11y Access -- 和 animations),同时通过组成增加你的习惯风格或逻辑。

You can also try and create HOCs (Higher-Order Components) that wrap NextUI components, adding or modifying functionality as needed. That approach allows you to reuse NextUI s features while injecting additional props or styles.

If the customization involves logic more than styles, consider using custom hooks to encapsulate and reuse this logic across components.

这是一种典型的幻灯泡,似乎还没有解决,但我有另一种办法暂时解决这一问题:

import type { ForwardRefRenderFunction, ReactElement } from  react ;
import type { ButtonProps } from  @nextui-org/react ;

import { extendVariants, Button as BaseButton } from  @nextui-org/react ;

export const Button: ForwardRefRenderFunction<ReactElement, ButtonProps> = extendVariants(BaseButton, {
   variants: {
      color: {},
   },
   compoundVariants: [],
});




相关问题
store data in memory with nestjs

I am trying to persist some data in my nestjs server so I can then use that data in my client app through http requests. I have created a products.service.ts file with the function getAllData() that ...

React Hook Form Error on custom Input component

I am having a problem when I use react hook form + zod in my application, in short the inputs never change value and I get the following error in the console: Warning: Function components cannot be ...

Updatable promises using proxy in JavaScript

EDIT: I ve updated this question, and the old question is moved here. A POC can be found on this jsfiddle or the snippet below GOAL: The goal here is to make or rather simulate a promise that can be ...

热门标签