created a new array of objects using the spread operator.
I'm trying to use a map through this, but I don't think the definition of the type is right.
I think look at the redux toolkit react code, The definition of the interface PostState part seems to be invalid. But I don't know how to solve it
Using the redux toolkit, After the category was loaded, the data was made into a new array using the spread operator.
data
Code that you want to implement
{cartegory && cartegory.map((value, index) => {
return (
<Tab label={value.snippet.title} {...a11yProps(index)} key={value.id} />
)
})}
problem
Property 'snippet' does not exist on type '{}'. TS2339
TypeScript type
export type cartegory = {
kind: string
etag: string
id: string
snippet: {
publishedAt: string
channelId: string
title: string
description: string
thumbnails: {
default: {
url: string
width: number
height: number
}
medium: {
url: string,
width: number,
height: number
}
high: {
url: string,
width: number,
height: number
}
standard: {
url: string,
width: number,
height: number
}
maxres: {
url: string,
width: number,
height: number
}
}
channelTitle: string,
playlistId: string,
position: 0
resourceId: {
kind: string,
videoId: string
}
videoOwnerChannelTitle: string
videoOwnerChannelId: string
}
}[]
redux toolkit react ts code
import type { PayloadAction } from "@reduxjs/toolkit";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
import { youTubeAcsses } from '../apis/keys';
import { youtubeResponse, cartegory } from "../getTypes";
interface PostState {
loading: boolean;
error: string | null;
data: youtubeResponse | null;
cartegory: cartegory | {}[]
}
const initialState = {
loading: false,
error: null,
data: null,
cartegory : []
} as PostState;
// ACTION
export const youtubeList_Playlist = createAsyncThunk(
"GET/YOUTUBE_CHANNELID",
async (channelId: string, thunkAPI) => {
try {
const { data } = await axios.get<youtubeResponse>(
`https://www.googleapis.com/youtube/v3/playlists?key=${youTubeAcsses.apiKey}&channelId=${channelId}&part=snippet&maxResults=30`
// channelId=UCvpIHsNLXfpOj_uMgI62I2A - 그리곰 픽쳐스 상업 유튜브 채널
)
return data
} catch (err: any) {
return thunkAPI.rejectWithValue({
errorMessage: '호출에 실패했습니다.'
})
}
}
);
// SLICE
const youtube_PlaylistSlice = createSlice({
name: "YOUTUBE_PLAYLIST",
initialState,
reducers: {},
// createAsyncThunk 호출 처리 = extraReducers
extraReducers(builder) {
builder
.addCase(youtubeList_Playlist.pending, (state, action) => {
state.loading = true;
})
.addCase(youtubeList_Playlist.fulfilled, (state, action: PayloadAction<youtubeResponse>) => {
state.loading = false;
state.data = action.payload;
state.cartegory = [...state.data.items, ...action.payload.items]
})
.addCase(youtubeList_Playlist.rejected, (state, action: PayloadAction<any>) => {
state.error = action.payload;
});
},
});
export default youtube_PlaylistSlice.reducer;
Please give me some advice
CodePudding user response:
interface PostState {
loading: boolean;
error: string | null;
data: youtubeResponse | null;
cartegory: cartegory | {}[] // <-- here
}
That type is cartegory | {}[]
which means that value can either be cartegory
or an array of empty objects. And those empty objects don't have a snippet
property.
You can either remove that | {}[]
to make it simply:
interface PostState {
loading: boolean;
error: string | null;
data: youtubeResponse | null;
cartegory: cartegory // <-- here
}
Or you can check to make the property exists before you access it.
{cartegory && cartegory.map((value, index) => {
if ('snippet' in value) {
return (
<Tab label={value.snippet.title} {...a11yProps(index)} key={value.id} />
)
}
return null
})}