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

TypeScript中使用@emoji-mart/react的Picker组件报错求助

解决@emoji-mart/react组件的TypeScript类型错误

遇到的错误

JSX element type 'Picker' does not have any construct or call signatures.ts(2604)
'Picker' cannot be used as a JSX component.
Its type 'typeof import("@emoji-mart/react", { with: { "resolution-mode": "import" } })' is not a valid JSX element type.ts(2786)

组件代码

import data from "@emoji-mart/data";
import Picker from "@emoji-mart/react";
import { SetStateAction, useState } from "react";
import { FaRegSmile } from "react-icons/fa";
import { useTheme } from "../../../Contexts/ThemeContext/ThemeContext.tsx";

export default function EmojiPickerContainer() {
  const [emojiPickerDisplay, setEmojiPickerDisplay] = useState(false);
  const [currentEmoji, setCurrentEmoji] = useState(null);
  const { getTheme } = useTheme();

  const buttonClickHandler = () => {
    setEmojiPickerDisplay(true);
  };

  const emojiSelectHandler = (emoji: { native: SetStateAction<null> }) => {
    setCurrentEmoji(emoji.native);
    setEmojiPickerDisplay(false);
  };

  console.log(currentEmoji);

  return (
    <div className="relative inline-block">
      {!emojiPickerDisplay && (
        <button
          className="ml-2 p-2 text-2xl rounded border border-gray-500 bg-gray-100 dark:bg-zinc-600 text-black  hover:bg-gray-300  dark:text-white  focus:outline-none"
          onClick={buttonClickHandler}
        >
          <b>
            <FaRegSmile />
          </b>
        </button>
      )}
      {emojiPickerDisplay && (
        <div className="absolute bottom-full right-0 mb-2 z-50">
          <div className="overflow-y-auto  max-w-60 max-h-100 w-full border border-gray-300 rounded-lg shadow-lg bg-white dark:bg-gray-800 scrollbar-thin">
            <Picker
              data={data}
              onEmojiSelect={emojiSelectHandler}
              theme={getTheme() === "dark" ? "dark" : "light"}
              previewPosition="none"
            />
          </div>
        </div>
      )}
    </div>
  );
}

已尝试的操作

  • 创建了自定义类型声明文件src/types/emoji-mart-react.d.ts:
// src/types/emoji-mart-react.d.ts
declare module '@emoji-mart/react' {
  import * as React from 'react';

  interface PickerProps {
    data: any;
    onEmojiSelect: (emoji: any) => void;
    theme?: string;
    previewPosition?: string;
    // Add other props as needed
  }

  export const Picker: React.FC<PickerProps>;
}
  • 在tsconfig.json的compilerOptions中添加:
"typeRoots": ["./node_modules/@types", "./src/types"],

解决方案

1. 修正Picker的导入方式

@emoji-mart/react的Picker是命名导出而非默认导出,当前默认导入会把整个模块对象赋值给Picker,导致类型不匹配。修改导入语句:

// 原代码
import Picker from "@emoji-mart/react";

// 修改为
import { Picker } from "@emoji-mart/react";

2. 完善类型声明(可选)

若调整导入后仍有类型提示问题,可优化自定义类型声明,替换模糊的any为具体类型:

// src/types/emoji-mart-react.d.ts
declare module '@emoji-mart/react' {
  import * as React from 'react';

  export interface EmojiData {
    native: string;
    id: string;
    name: string;
    // 按需补充其他emoji属性
  }

  export interface PickerProps {
    data: Record<string, any>;
    onEmojiSelect: (emoji: EmojiData) => void;
    theme?: 'light' | 'dark';
    previewPosition?: 'top' | 'bottom' | 'none';
    // 补充其他需要的props
  }

  export const Picker: React.FC<PickerProps>;
}

3. 修正组件内的类型错误

  • 给currentEmoji的useState指定明确类型:
const [currentEmoji, setCurrentEmoji] = useState<string | null>(null);
  • 修正emojiSelectHandler的参数类型:
const emojiSelectHandler = (emoji: EmojiData) => {
  setCurrentEmoji(emoji.native);
  setEmojiPickerDisplay(false);
};

4. 确保TypeScript识别自定义类型

检查tsconfig.json的include配置,确保包含src/types目录:

{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types", "./src/types"],
    // 其他配置
  },
  "include": ["src/**/*"]
}

5. 重启TypeScript服务器

若修改后错误仍未消失,重启VS Code的TypeScript服务器:

  • 打开命令面板(Ctrl+Shift+P / Cmd+Shift+P)
  • 选择TypeScript: Restart TS Server

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:05:04