Почему Typescript выдает ошибку при вводе параметра вызова Redux-saga - TS2339 - PullRequest
0 голосов
/ 07 марта 2019

работает с ошибкой ввода TS2339 с TS, утверждая, что я не могу найти параметр, определенный в типе интерфейса.Ниже приведены два файла, которые у меня есть:

api-service-saga.ts

  • Ошибка в строке const res = yield call(fetchAllBooks, action.param);
  • Жалуется, что свойство param(тип IBookAction из ../actions) не существует в IBookAction, а также в ILoadSearchableBooks
import { takeEvery, call, put } from 'redux-saga/effects';
import { Action, IBookAction } from '../actions';
import { fetchAllBooks } from '../service/books-service';
import { Book } from '../classes';

export default function* watcherSaga() {
    yield takeEvery(Action.FETCH_SEARCHABLE_BOOKS, searchableBooksSaga);
}

function* searchableBooksSaga(action: IBookAction) {
    try {
        const res = yield call(fetchAllBooks, action.param);
        const searchableBooks = res.data.reduce((books: Array<Book>, b: any) => {
            books.push(new Book(b));
            return books;
        }, [])
        yield put({ type: Action.LOAD_SEARCHABLE_BOOKS, searchableBooks });
    } catch (e) {
        yield put({ type: Action.FETCH_ERROR, error: e});
    }

}

И ниже находится файл, в котором я определил интерфейсы:

.. / actions / index.ts

import { Action } from './action-constants';
import { Book } from '../classes';

export interface IAction {
    type: Action
}

// TODO: refactor into other action files if it gets too large.

// Nav Actions

export interface INavigateAction extends IAction {
    payload: string
}

export function navigateAction(newState: any): INavigateAction {
    console.log('Navigating to::', newState);
    return { type: Action.NAVIGATE_TO, payload: newState }
}

// Book Actions

export interface IFetchSearchableBookAction extends IAction {
    param: any // TODO: properly type the parameters.
}
export function fetchSerachableBooks(param: any): IBookAction {
    console.log('Fetching Searchable Books:', param);
    return { type: Action.FETCH_SEARCHABLE_BOOKS, param }
}

export interface ILoadSearchableBooks extends IAction {
    searchableBooks: Array<Book>
}

export { Action } from './action-constants';
export type IBookAction = IFetchSearchableBookAction | ILoadSearchableBooks;

Как видно из последней строки, я экспортирую типы IBookAction, одним из которых является IFetchSearchableBookAction со свойством param.

Полная ошибка, которую я получаю:

TS2339: Property 'param' does not exist on type 'IBookAction'.
Property 'param' does not exist on type 'IFetchSearchableBookAction'

1 Ответ

1 голос
/ 07 марта 2019

Поскольку IBookAction может быть либо IFetchSearchableBookAction, либо ILoadSearchableBooks, а ILoadSearchableBooks не имеет param проп. Это означает, что только на 50% можно убедиться, что action имеет param проп, но не на 100%.

Что если action будет ILoadSearchableBooks, а не IFetchSearchableBookAction, тогда param, вероятно, будет undefined.

Обходной путь - набрать guard, чтобы Typescript знал, что это action действительно IFetchSearchableBookAction, а не ILoadSearchableBooks.

Например:

function searchableBooksSaga(action: ILoadSearchableBooks | IFetchSearchableBookAction) {
  if ('param' in action) {
    const param = action.param;
  } else {
    const books = action.searchableBooks;
  }
}

Более подробную информацию о том, как печатать охранник, можно найти в Typescript здесь

...