首页 > 解决方案 > TypeScript 错误地推断 React 中的变量类型...?

问题描述

我目前正在通过一个 React 项目学习 TypeScript,该项目涉及与来自 Spotify Web API 的数据进行交互。我有点编程菜鸟,所以我不知道我是否遗漏了一些明显的东西,但似乎 TypeScript 在我的代码中的某处错误地推断类型,这真的让我感到困惑。

基本上,这个想法是让用户(通过一个 React 函数组件)能够看到他们 Spotify 库中所有艺术家的列表,并且对于每个艺术家,他们可以看到他们在他们的库中拥有的歌曲列表那个艺术家。例如:

滚石乐队:

  • Start Me Up -纹身你
  • Rocks Off -在大街上流放
  • ETC...

我有一个“服务器”生成器,它通过调用其他函数来处理用户播放列表的曲目和用户保存的曲目。完成后,它会生成一个对象,其键是艺术家姓名,其各自的值是表示艺术家创建的曲目的对象数组(希望这是有道理的)。这不是一个特别快的过程,所以我想同时产生一些值,以便用户可以看到生成器处理他们的 Spotify 库的进度。

这是获取数据的“服务器”函数:

export async function* fetchAllArtistsAndTracks2(accessToken: string, refreshToken: string) {

    const currentUserProfile = await fetchCurrentUserProfile(accessToken, refreshToken);


    interface ArtistsAndTracks {
        [artist: string]: Array<APITrackObject>
    }
    const artistsAndTracks: ArtistsAndTracks = {};

    interface YieldObject { // THIS IS RELEVANT TO MY QUESTION (I THINK)
        objKeys: Array<string>,
        type: string,
        count: number
    }


    let playlistCount: number = 0;

    const allPlaylists = fetchAllPlaylists(accessToken, 50);
    for await (let playlistBatch of allPlaylists) {

        for (let i = 0; i < playlistBatch.length; i++) {

            const playlist = playlistBatch[i];
            
            if (playlist.owner.id !== currentUserProfile.id) continue;
            if (playlist.name === "Discover Weekly" || playlist.name === "Discover Weekly Archive") continue;

            const playlistTracks = await fetchTracksFromPlaylistTracksHREF2(accessToken, playlist.tracks.href, currentUserProfile);
            
            for (let track of playlistTracks) {

                const artists = track.artists.map((obj: ArtistFromTrack) => obj.name);

                artists.forEach((artist: string) => {
                    if (!Object.keys(artistsAndTracks).includes(artist)) {
                        artistsAndTracks[artist] = [track];
                    } else if (!artistsAndTracks[artist].some((artistTrack: APITrackObject) => artistTrack.id === track.id)) {
                        artistsAndTracks[artist].push(track);
                    }
                });

            }

            if (playlistCount <= i) playlistCount = i + 1;
            else playlistCount += 1;
            
            const obj: YieldObject = { // YieldObject is defined at the top
                objKeys: Object.keys(artistsAndTracks),
                type: "playlists",
                count: playlistCount
            }
            yield obj;
        }
    }


    let trackCount:number = 0;

    const allSavedTracks = fetchAllSavedTracks(accessToken, 50);
    for await (let trackBatch of allSavedTracks) {

        for (let track of trackBatch) {

            const artists = track.artists.map((obj: ArtistFromTrack) => obj.name);

            artists.forEach((artist: string) => {

                if (!Object.keys(artistsAndTracks).includes(artist)) {
                    artistsAndTracks[artist] = [track];
                } else if (!artistsAndTracks[artist].some((artistTrack: APITrackObject) => artistTrack.id === track.id)) {
                    artistsAndTracks[artist].push(track);
                }

            });

            trackCount += 1;
            const obj: YieldObject = {
                objKeys: Object.keys(artistsAndTracks),
                type: "tracks",
                count: trackCount
            }
            yield obj;
        }
    }
    yield artistsAndTracks;
}

在我的一个组件中,有一个useEffect包含此函数的函数,它遍历生成器。

        async function fetchData() {
            const generator = fetchAllArtistsAndTracks2(props.accessToken, props.refreshToken);
            for await (let entry of generator) {
                try {
                    if (entry.type === "playlists") setPlaylistProgress(entry.count);
                    else setTrackProgress(count);
                } catch (error) {
                    setArtistsAndTracks(entry);
                }
            }
        }

这是我得到的错误:

Argument of type 'number | APITrackObject[]' is not assignable to parameter of type 'SetStateAction<number>'.
  Type 'APITrackObject[]' is not assignable to type 'SetStateAction<number>'.
    Type 'APITrackObject[]' is not assignable to type 'number'.  TS2345

    152 |                     // entry.objKeys;
    153 | 
  > 154 |                     if (entry.type === "playlists") setPlaylistProgress(entry.count);
        |                                                                         ^
    155 |                     else setTrackProgress(count);
    156 |                 } catch (error) {
    157 |                     setArtistsAndTracks(entry);

所以我假设这与fetchAllArtistsAndTracks2产量有关。但是我不知道为什么编译器在谈论APITrackObject(在另一个文件中定义的接口),所以我不知道如何修复这个错误。

如果有人知道我应该做什么,我将非常感激,因为我完全被难住了。先感谢您!

标签: reactjstypescriptreact-hookstypescript-typingsreact-functional-component

解决方案


推荐阅读