Preact forwardRef组件JSR TypeScript类型标注问题求助
Preact forwardRef按钮组件JSR类型标注问题解决
问题背景
我基于Preact开发了一个使用forwardRef的按钮组件,在JSR的TypeScript环境中,平台要求公开API的所有符号必须添加明确的类型标注。我尝试给组件返回值指定HTMLButtonElement、JSX.Element或JSX.IntrinsicElements["button"]类型均无效,现附上代码及错误提示,寻求解决方案。
原组件代码
import { forwardRef } from "preact/compat"; import type { ButtonProps } from "./type.ts"; import { useButton } from "./use-button.ts"; import LoadingSpinner from "../../icon/LoadingSpinner.tsx"; import type { JSX } from "preact/jsx-runtime"; import { UseButtonReturn } from "./index.ts"; const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => { const { children, className, isDisabled, GetVariantButton, isLoading, GetButtonProps, GetSpinnerProps, GetDisabled, endContent, startContent, GetSlot, ...otherProps } = useButton({ ...props }); const LoadSpinner = ( <LoadingSpinner className={`${GetSpinnerProps?.className} ${GetSlot.yuzuSpinner}`} /> ); return ( <> <button {...otherProps} className={`flex flex-row items-center justify-center gap-2 ${className} ${GetDisabled} ${GetButtonProps.className} ${GetVariantButton} ${GetSlot.yuzuBase} ${GetSlot.yuzuDisabled}`.trim()} disabled={isDisabled} ref={ref} > {startContent ? startContent : null} {children} {endContent ? endContent : null} {isLoading ? LoadSpinner : null} </button> </> ); }); export default Button;
无效尝试
我曾尝试给组件函数指定返回值类型,但这种写法不符合语法要求:
// 无效写法 const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref): JSX.Element || JSX.IntrinsicElements["button"] => {});
错误提示
Checking for slow types in the public API... error[missing-explicit-type]: missing explicit type in the public API | 61 | const Button= forwardRef<HTMLButtonElement, ButtonProps>((props,ref) => { | ^^^^^^ 该符号缺少明确的类型标注 | = hint: 为该符号添加明确的类型标注 info: 公开API中的所有符号都必须有明确的类型
解决方案
问题核心是JSR要求导出的变量本身必须有显式类型标注,而非仅依赖forwardRef的泛型参数推导。我们需要给Button变量直接指定Preact提供的ComponentWithForwardedRef类型:
- 首先导入
ComponentWithForwardedRef类型:
import type { ComponentWithForwardedRef } from "preact/compat";
- 给
Button变量添加显式类型标注:
const Button: ComponentWithForwardedRef<HTMLButtonElement, ButtonProps> = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => { // 组件逻辑保持不变 });
修改后的完整代码
import { forwardRef } from "preact/compat"; import type { ComponentWithForwardedRef } from "preact/compat"; // 新增类型导入 import type { ButtonProps } from "./type.ts"; import { useButton } from "./use-button.ts"; import LoadingSpinner from "../../icon/LoadingSpinner.tsx"; import type { JSX } from "preact/jsx-runtime"; import { UseButtonReturn } from "./index.ts"; // 显式指定Button的类型 const Button: ComponentWithForwardedRef<HTMLButtonElement, ButtonProps> = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => { const { children, className, isDisabled, GetVariantButton, isLoading, GetButtonProps, GetSpinnerProps, GetDisabled, endContent, startContent, GetSlot, ...otherProps } = useButton({ ...props }); const LoadSpinner = ( <LoadingSpinner className={`${GetSpinnerProps?.className} ${GetSlot.yuzuSpinner}`} /> ); return ( <> <button {...otherProps} className={`flex flex-row items-center justify-center gap-2 ${className} ${GetDisabled} ${GetButtonProps.className} ${GetVariantButton} ${GetSlot.yuzuBase} ${GetSlot.yuzuDisabled}`.trim()} disabled={isDisabled} ref={ref} > {startContent ? startContent : null} {children} {endContent ? endContent : null} {isLoading ? LoadSpinner : null} </button> </> ); }); export default Button;
说明
ComponentWithForwardedRef<RefType, PropsType>是Preact专门为forwardRef组件提供的类型,它准确描述了带转发ref的组件类型,完全符合JSR对公开API类型标注的要求。
内容的提问来源于stack exchange,提问作者Yuzu Airi
相关产品推荐
相关产品推荐

