Mam projektu TypeScript, który używa React i Redux i próbuję dodać niektóre funkcje middleware. I zaczęło poprzez realizację jednego z próbek Redux jest tak:Jak utworzyć silnie typowane oprogramowanie pośrednie redux w języku TypeScript z definicji typów Redux?
// ---- middleware.ts ----
export type MiddlewareFunction = (store: any) => (next: any) => (action: any) => any;
export class MyMiddleWare {
public static Logger: MiddlewareFunction = store => next => action => {
// Do stuff
return next(action);
}
}
// ---- main.ts ----
import * as MyMiddleware from "./middleware";
const createStoreWithMiddleware = Redux.applyMiddleware(MyMiddleWare.Logger)(Redux.createStore);
Powyższe działa dobrze, ale ponieważ jest to maszynopis Chciałbym, aby to silnie wpisane, najlepiej przy użyciu typów zdefiniowanych przez Redux więc don Muszę wymyślić i utrzymać własne. Więc tutaj są odpowiednie fragmenty z mojego pliku index.d.ts dla Redux:
// ---- index.d.ts from Redux ----
export interface Action {
type: any;
}
export interface Dispatch<S> {
<A extends Action>(action: A): A;
}
export interface MiddlewareAPI<S> {
dispatch: Dispatch<S>;
getState(): S;
}
export interface Middleware {
<S>(api: MiddlewareAPI<S>): (next: Dispatch<S>) => Dispatch<S>;
}
Próbuję dowiedzieć się, jak doprowadzić te typy do mojego sposobu Logger ale nie mam dużo szczęścia. Wydaje mi się, że coś takiego powinno działać:
interface MyStore {
thing: string;
item: number;
}
interface MyAction extends Action {
note: string;
}
export class MyMiddleWare {
public static Logger: Middleware = (api: MiddlewareAPI<MyStore>) => (next: Dispatch<MyStore>) => (action: MyAction) => {
const currentState: MyStore = api.getState();
const newNote: string = action.note;
// Do stuff
return next(action);
};
}
ale zamiast ja dostać ten błąd:
błąd TS2322: Type „(API: MiddlewareAPI) => (dalej: Dispatch) => (action: Action) => Action 'nie można przypisać' Middleware '.
Typy parametrów "api" i "api" są niekompatybilne.
Typ 'MiddlewareAPI' nie można przypisać "MiddlewareAPI".
Typ "S" nie może być przypisany do "MyStore".
widzę <S> generic zadeklarowane w definicji typu, ale próbowałem wiele różnych kombinacji i nie mogę wydawać się, aby dowiedzieć się, jak określić go jako MyStore tak, że jest uznawany za rodzajowy w pozostałych deklaracjach. Na przykład, zgodnie z deklaracją api.getState() powinien zwrócić obiekt MyStore. To samo myślenie dotyczy oczywiście typu działania: <A>.
Żadne z nich nie odpowiada na pytanie (które zaktualizuję w celu wyjaśnienia), ponieważ wywołania api.getState() nie zwracają silnie wpisanego obiektu. Chodzi o to, aby kompilator stosował się do deklaracji typu, ponieważ są one zdefiniowane, więc nie musisz wykonywać żadnych dodatkowych rzutów. Najpierw musisz to zrobić: const currentState: MyStore = api.getState() jak każdy jako MyStore; Po drugie trzeba jeszcze to zrobić: const currentState: MyStore = api.getState() jako MyStore; –
@BernardHymmen czy kiedykolwiek to rozgryzłeś? – NSjonas
@NSjonas - Przepraszamy za brak odpowiedzi wcześniej. Mój kolega zwrócił uwagę, że definicje typów uniemożliwiły strukturalnie stworzenie ściśle wpisanego oprogramowania pośredniego w sposób bezpośredni. Najlepsze, co możesz zrobić, to zaimplementować jakąś pracę, jak to sugerował Martin Backschat. W zasadzie to właśnie robiłem, chociaż nie wiedziałem o tworzeniu strażników typowych za pomocą "jest" w tym czasie, więc moje rozwiązanie nie było tak ładne jak u Martina. FWIW: Wygląda na to, że ludzie pracowali nad tym problemem (https://github.com/reactjs/redux/pull/2563), ale nie próbowałem jeszcze tych zmian. –