Interfață TypeScript care permite alte proprietăți
În rezumat, este posibil să ai o interfață care declară câteva proprietăți de bază, dar care să nu restricționeze proprietăți suplimentare? Aceasta este situația mea actuală:
Folosesc modelul Flux, care definește un dispecer generic:
class Dispatcher<TPayload> {
dispatch(arg:TPayload):void { }
}
Apoi creez un dispatcher cu propriul meu tip de payload, astfel:
interface ActionPayload {
actionType: string
}
const dispatcher = new Dispatcher<ActionPayload>();
Acum am niște cod de acțiune care ar trebui să trimită o sarcină utilă cu unele date suplimentare, dar interfața ActionPayload permite doar actionType. Cu alte cuvinte, acest cod:
interface SomePayload extends ActionPayload {
someOtherData: any
}
class SomeActions {
doSomething():void {
dispatcher.dispatch({
actionType: "hello",
someOtherData: {}
})
}
}
Dă o eroare de compilare deoarece someOtherData nu corespunde cu interfața ActionPayload. Problema este că multe clase diferite de „acțiune” vor folosi același dispatcher, așa că, deși aici este someOtherData, acolo ar putea fi anotherKindOfData, și așa mai departe. În momentul de față, tot ce pot face pentru a acomoda asta este să folosesc new Dispatcher<any>() deoarece diferite acțiuni vor fi distribuite. Toate acțiunile împărtășesc totuși o bază ActionPayload, așa că speram să pot restrânge tipul ca new Dispatcher<extends ActionPayload>() sau ceva de genul acesta. Este posibil așa ceva?
Răspuns #1
Dacă vrei ca ActionPayload să accepte orice altă proprietate, poți adăuga un indexator:
interface ActionPayload {
actionType: string;
// Keys can be strings, numbers, or symbols.
// If you know it to be strings only, you can also restrict it to that.
// For the value you can use any or unknown,
// with unknown being the more defensive approach.
[x: string | number | symbol]: unknown;
}
Vezi https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#strict-object-literal-assignment-checking
Răspunsul #2
interface Options {
darkMode?: boolean;
[otherOptions: string]: unknown;
}
