Что такое эквивалентный интерфейс к типу "AppThunk" из Redx документов? - PullRequest
0 голосов
/ 25 февраля 2020

Документы Redux содержат это:

import { configureStore, Action } from '@reduxjs/toolkit'
import { ThunkAction } from 'redux-thunk'

import rootReducer, { RootState } from './rootReducer'

const store = configureStore({
  reducer: rootReducer
})

if (process.env.NODE_ENV === 'development' && module.hot) {
  module.hot.accept('./rootReducer', () => {
    const newRootReducer = require('./rootReducer').default
    store.replaceReducer(newRootReducer)
  })
}

export type AppDispatch = typeof store.dispatch

export type AppThunk = ThunkAction<void, RootState, null, Action<string>>

export default store
  1. Почему автор здесь использует type вместо interface? Я прочитал ответ о разнице между типами и интерфейсами , но до сих пор не понимаю, зачем кому-то использовать тип вместо интерфейса?
  2. Каким будет интерфейсный эквивалент этих линии?
export type AppDispatch = typeof store.dispatch
export type AppThunk = ThunkAction<void, RootState, null, Action<string>>

1 Ответ

1 голос
/ 25 февраля 2020

Я - сопровождающий Redux, и я думаю, что, возможно, я написал этот конкретный фрагмент.

Я не полный эксперт по TS, поэтому в некотором смысле весь "type против interface «Меня это тоже немного смущает.

Если вы посмотрите на оригинальный ThunkAction тип из redux-thunk набрав , вы увидите, что он определен с помощью ключевого слова type:

export type ThunkAction<
  TReturnType,
  TState,
  TExtraThunkArg,
  TBasicAction extends Action
> = (
  dispatch: ThunkDispatch<TState, TExtraThunkArg, TBasicAction>,
  getState: () => TState,
  extraArgument: TExtraThunkArg,
) => TReturnType;

Насколько я понимаю, TS interface может расширять еще один interface, но interface никогда не может расширять type. So, the fact that ThunkAction is defined as a тип means that AppThunk _must_ also be a type.

Гипотетически, вы можете определить ThunkAction как interface, что, как я думаю будет выглядеть так:

interface ThunkAction {
    // declaring a signature here without a field name means this is describing
    // a function that matches this signature, vs an object field
    <
      TReturnType,
      TState,
      TExtraThunkArg,
      TBasicAction extends Action
    > = (
      dispatch: ThunkDispatch<TState, TExtraThunkArg, TBasicAction>,
      getState: () => TState,
      extraArgument: TExtraThunkArg,
    ) => TReturnType
}

Однако на практике это кажется, что объявление типов функций с использованием interface - редкий случай использования. Интерфейсы обычно используются для объектов, а type для всего, что не является строго объектом или является производным типом.

Для AppDispatch, это производный тип, использующий typeof, поэтому имеет будет type.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...