TypeScriptError: тип 'Data' не может быть назначен типу 'string'

Я использую React-typescript для своего приложения. для управления состоянием я использую Redux-toolkit. Я получаю один открытый API и сохраняю его в моем магазине redux. Я создал диспетчерскую функцию. Из компонента, когда я нажимаю функцию отправки, отображается случайное изображение собаки. Но проблема в том, что после сопоставления, когда я использую этот img src. Я получаю машинную ошибку: Type 'Data' is not assignable to type 'string'. Я не понимаю, что делаю неправильно. я загрузил свой код в codeandbox, хотя он работает вcodeandbox, но не работает в моем приложении.

Пс. Я не загружал код настройки своего магазина, потому что он работает, найдите ☺️.

Это мой редуктор

    /* eslint-disable @typescript-eslint/indent */
    import { createSlice, PayloadAction } from '@reduxjs/toolkit';
    import { AppThunk } from "store/store";
    
    interface IMeta {
      loading: boolean;
      error: boolean;
      message: string;
    }
    
    interface Data {
      src: string;  
    }
    
    interface IDogs {
      meta: IMeta;
      dogs: Data[];
    }
    
    const initialState: IDogs = {
      "meta": {
        "loading": false,
        "error": false,
        "message": ``
      },
      "dogs": []
    };
    
    const dogSlice = createSlice({
      "name": `random-dogs`,
      initialState,
      "reducers": {
        loadState(state) {
          state.meta = {
            "loading": true,
            "error": false,
            "message": ``
          };
          state.dogs = [];
        },
        fetchData(state, action: PayloadAction<Data[]>) {
          state.meta.loading = false;
          state.dogs = action.payload;
          console.log(`dogs`, action.payload);
        },
        loadFailed(state, action: PayloadAction<string>) {
          state.meta = {
            "loading": false,
            "error": true,
            "message": action.payload
          };
          state.dogs = [];
        }
      }
    
    });
    
    export const { loadState, fetchData, loadFailed } = dogSlice.actions;
    export default dogSlice.reducer;
    
    export const fetchDogs = (): AppThunk => async (dispatch) => {
      const url = `https://dog.ceo/api/breeds/image/random/5`;
    
      try {
        dispatch(loadState);
        const response = await fetch(url);
        const data = await response.json();
        console.log(data);
        console.log(data.message);
        const singleData = data.message.map((i) => i);
        dispatch(fetchData(singleData));
      } catch (error) {
        dispatch(loadFailed(`dogs are unavailable`));
        console.log({ error });
      }
    };

Это компонент, который я использую в магазине redux

    import React, { memo } from 'react';
    import { useSelector, useDispatch } from 'react-redux';
    import { fetchDogs } from 'store/dogs';
    import { RootState } from 'store/combineReducer';
    
    export default memo(() => {
      const state = useSelector((rootState: RootState) => ({
        "dogs": rootState.fetchDogs.dogs,
        "meta": rootState.fetchDogs.meta
      }));
      const dispatch = useDispatch();
      console.log(`Dog component`, state.dogs[0]);
    
      return (
        <div>
          {state.meta.loading ? <p>loading....</p> :
            state.dogs.map((i, index) =>
              <div key={index}>
                <ul>
                  <li>{i}</li> // I can see the strings
                </ul>
                <img style={{ "width": 50, "height": 50 }} src={i} /> //getting error in here
              </div>)}
          <br></br>
          <button onClick={() => dispatch(fetchDogs())}> display random dogs</button>
        </div>
      );
    });


person Krisna    schedule 21.07.2020    source источник
comment
i на самом деле является целым числом. Вы можете попробовать принудительно использовать это как _2 _ $ {i} } />   -  person Lhew    schedule 21.07.2020


Ответы (1)


Ситуация следующая:

  • Интерфейс IDog имеет свойство dog типа Data [].
  • Данные имеют свойство src типа String.
  • Атрибут src img должен быть строкой.

Теперь вы проходите IDogs.dogs. Вам нужно углубиться в IDogs.dogs.src, чтобы получить нужную исходную строку.

Итак, строка 25 файла App.tsx должна выглядеть так, и, похоже, все работает нормально:

<img style={{ width: 50, height: 50 }} src={i.src} alt="dog" />

PS: Пример codeandbox все еще работает, поскольку он, по-видимому, предполагает какое-то предположение, что вам нужно свойство src, но, как вы видите, вы все равно получаете ошибку.


ИЗМЕНИТЬ: после некоторой игры ответ будет таким, как показано ниже. Однако это связано с тем, что было написано выше.

Я скачал ваш проект и попытался запустить его в npm на своем ПК. Я сделал 2 вещи, чтобы заставить его работать:

  1. Я обновил строку 25, чтобы использовать приведение: src={String(i)}
  2. Обновил response-скрипты. См. Эту ветку для справки: TypeError [ERR_INVALID_ARG_TYPE]: аргумент пути должен быть строкового типа. Полученный тип undefined возникает при запуске приложения реакции
person SnowGroomer    schedule 21.07.2020
comment
когда я пробовал с <li>{i.src}</li>, он тоже не отображал список. - person Krisna; 21.07.2020
comment
На самом деле, я думаю, что это не обязательно проблема. Кастинг, похоже, решил проблему, вы пробовали в своем проекте? src={String(i)} - person SnowGroomer; 21.07.2020
comment
Я скачал ваш проект и попытался запустить его в npm на своем ПК. Я сделал 2 вещи, чтобы заставить его работать. См. Обновленный ответ. - person SnowGroomer; 21.07.2020