如何解决use-sound模块声明文件无法解析的TypeScript问题?
问题描述
执行npm i use-sound安装库后,在React组件中使用时出现模块类型识别错误,错误信息如下:
Could not find a declaration file for module 'use-sound'. 'c:/Users/Maor/Projects/FullStack-Spotify-Clone/spotify-clone/node_modules/use-sound/dist/use-sound.esm.js' implicitly has an 'any' type.
There are types at 'c:/Users/Maor/Projects/FullStack-Spotify-Clone/spotify-clone/node_modules/use-sound/dist/index.d.ts', but this result could not be resolved when respecting package.json "exports".
The 'use-sound' library may need to update its package.json or typing.
项目依赖片段:
"dependencies": { "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-slider": "^1.1.2", "@supabase/auth-helpers-nextjs": "^0.8.1", "@supabase/auth-helpers-react": "^0.4.2", "@supabase/auth-ui-react": "^0.4.5", "@supabase/auth-ui-shared": "^0.1.7", "next": "^13.5.5", "query-string": "^8.1.0", "react": "latest", "react-dom": "latest", "react-hook-form": "^7.47.0", "react-hot-toast": "^2.4.1", "react-icons": "^4.11.0", "stripe": "^13.9.0", "tailwind-merge": "^1.14.0", "uniqid": "^5.4.0", "use-sound": "^4.0.1", "zustand": "^4.4.3" },
组件中使用use-sound的代码片段:
"use client"; import { Song } from "@/types"; import MediaItem from "./MediaItem"; import LikedButton from "./LikedButton"; import Slider from "./Slider"; import useSound from "use-sound"; import { BsPauseFill, BsPlayFill } from "react-icons/bs"; import { AiFillStepBackward, AiFillStepForward } from "react-icons/ai"; import { HiSpeakerWave, HiSpeakerXMark } from "react-icons/hi2"; import usePLayer from "@/hooks/usePlayer"; import { useState } from "react"; interface PlayerContentProps { song: Song; songUrl: string; } const PlayerContent: React.FC<PlayerContentProps> = ({ song, songUrl }) => { const player = usePLayer(); const [volume, setVolume] = useState(1); const [isPlaying, setIsPlaying] = useState(false); const Icon = isPlaying ? BsPauseFill : BsPlayFill; const VolumeIcon = volume === 0 ? HiSpeakerXMark : HiSpeakerWave; const onPlayNext = () => { if (player.ids.length === 0) { return; } const currentIndex = player.ids.findIndex((id) => id === player.activeId); const nextSong = player.ids[currentIndex + 1]; if (!nextSong) { return player.setId(player.ids[0]); } player.setId(nextSong); }; const onPlayPrevious = () => { if (player.ids.length === 0) { return; } const currentIndex = player.ids.findIndex((id) => id === player.activeId); const previousSong = player.ids[currentIndex - 1]; if (!previousSong) { return player.setId(player.ids[player.ids.length - 1]); } player.setId(previousSong); }; const [play, { pause, sound }] = useSound(songUrl, { volume: volume, onPlay: () => setIsPlaying(true), onEnd: () => { setIsPlaying(false); onPlayNext(); }, onpause: () => setIsPlaying(false), format: ["mp3"], }); }
解决方案
方案1:修正use-sound的package.json(临时解决)
找到项目中node_modules/use-sound/package.json,修改exports字段,确保类型声明文件被正确映射:
"exports": { ".": { "import": "./dist/use-sound.esm.js", "require": "./dist/use-sound.cjs.js", "types": "./dist/index.d.ts" } }
修改完成后,重启开发服务器或TypeScript服务。
方案2:自定义类型声明文件
在项目根目录创建types文件夹,新增use-sound.d.ts文件,内容如下:
declare module 'use-sound' { import type { Options, Sound } from 'use-sound/dist/types'; function useSound( src: string | string[], options?: Partial<Options> ): [() => void, Sound]; export default useSound; }
然后在tsconfig.json中配置类型目录:
{ "compilerOptions": { "typeRoots": ["./node_modules/@types", "./types"] } }
方案3:降级use-sound版本
4.x版本存在类型导出问题,可尝试降级到3.x稳定版本:
npm uninstall use-sound npm install use-sound@3.0.1
方案4:临时跳过类型检查(不推荐)
在组件文件顶部添加注释,跳过该模块的类型检查:
// @ts-ignore import useSound from "use-sound";
该方法会隐藏类型错误,仅作为应急临时方案。
内容的提问来源于stack exchange,提问作者Maor

