You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native + TypeScript传递动态组件时'onPress'属性不存在错误

解决TypeScript类型错误:为可点击组件抽象添加正确类型约束

问题核心在于你没有给TriggerComponent和triggerProps添加正确的类型约束,TypeScript无法确认传入的组件支持onPress属性。以下是具体解决方案:

1. 定义可点击组件的基础Props类型

首先创建一个类型,描述所有支持onPress的组件共有的属性:

type PressableProps = {
  onPress?: () => void;
  // 可根据需要添加其他通用属性,比如style、testID等
};

2. 使用泛型关联组件与Props

通过泛型让Menu组件的TriggerComponent和triggerProps类型严格关联,确保triggerProps符合组件的Props要求,同时排除我们要手动传入的onPress:

修改IMenu接口和Menu组件:

import { ReactNode, FunctionComponent, useRef, ElementRef } from 'react';
import {
  Menu as PMMenu,
  MenuOptions,
  MenuTrigger,
  withMenuContext,
} from 'react-native-popup-menu';
import { View } from 'react-native';

type PressableProps = {
  onPress?: () => void;
};

interface IMenu<T extends PressableProps> {
  children: ReactNode;
  ctx: {
    menuActions: {
      toggleMenu: (name: string) => void;
    };
  };
  TriggerComponent: FunctionComponent<T>;
  triggerProps: Omit<T, 'onPress'>; // 排除onPress,避免与手动传入的冲突
}

function Menu<T extends PressableProps>({
  ctx: { menuActions: { toggleMenu } },
  children,
  TriggerComponent,
  triggerProps,
}: IMenu<T>) {
  const menuRef = useRef<ElementRef<typeof MenuTrigger>>(null);

  // ... 你的其他逻辑代码

  return (
    <View>
      <TriggerComponent
        {...triggerProps}
        onPress={() => toggleMenu(menuRef.current?.props?.menuName)}
      />
      <PMMenu>
        <MenuTrigger ref={menuRef} />
        <MenuOptions customStyles={optionsStyles}>
          {children}
        </MenuOptions>
      </PMMenu>
    </View>
  );
}

3. 为什么这样能解决问题?

  • 泛型T确保TriggerComponent的Props包含onPress,TypeScript不再质疑onPress的合法性
  • Omit<T, 'onPress'>让triggerProps自动排除onPress,避免重复传入的冲突,同时严格匹配组件的其他Props要求
  • 相比使用any,这种方式保留了完整的类型检查,既能避免错误,又能获得TypeScript的类型提示

简化版(无需泛型)

如果不需要严格关联组件的具体Props,也可以直接约束TriggerComponent为支持onPress的函数组件:

type PressableComponent = FunctionComponent<PressableProps & Record<string, unknown>>;

interface IMenu {
  children: ReactNode;
  ctx: {
    menuActions: {
      toggleMenu: (name: string) => void;
    };
  };
  TriggerComponent: PressableComponent;
  triggerProps: Record<string, unknown>;
}

这种方式更灵活,但类型检查的严谨性稍弱,适合不需要严格校验triggerProps结构的场景。

内容的提问来源于stack exchange,提问作者usbToaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:45:40