reactjs - 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
(在另一个文件中定义的接口),所以我不知道如何修复这个错误。
- 所以编译器说问题出在
entry.count
. - 在“服务器”函数中,我通过接口指定
YieldObject
的类型obj.count
是number
,这应该没问题,因为obj.count
产生的两个值都是整数(即let playlistCount: number = 0;
和let trackCount: number = 0;
)。编译器让我没有 - 这就是我为 setPlaylistProgress: 定义可接受的参数类型的方式
const [ playlistProgress, setPlaylistProgress ] = useState<number>(0);
,它检查出来了。
如果有人知道我应该做什么,我将非常感激,因为我完全被难住了。先感谢您!
解决方案
推荐阅读
- python - Python Flask CSRF 令牌给出了意想不到的结果
- python - 在 Flask 中,有没有办法对除应用程序本身之外的所有人隐藏 @app.route。可以从 JSON 格式的 url 看到我的数据库
- antlr - Xtext/ANTLR:如何解决这个错误?以下令牌定义永远无法匹配...?
- android - 从 TypeScript 定义生成 Kotlin 声明的目的
- python - 不会注册或允许我在 python 中导入时间模块
- webforms - 我可以在 ASP.NET 网络表单中的站点主控内有一个表单吗
- java - Java Socket 服务器在读取数据时挂起
- django - 在 Django 中使用 API 以及如何显示数据
- c# - 在没有 libusb 的情况下在 C# 中获取 USB 设备描述符?
- ssl - oauth2_proxy 不要求身份验证