2017-01-18 2 views
2

Ich möchte eine Schnittstelle definieren, die über beliebige Eigenschaften verfügt, deren Typ immer gleich ist. Z.B.So definieren Sie eine Schnittstelle mit einer beliebigen Anzahl von Eigenschaften eines bestimmten Typs in TypeScript

type Reducer<S, P> = (state: S, payload: P) => S 

interface Reducers { 
    [name: string]: Reducer 
} 

und dann verwenden, etwa so:

interface MyState { 
    foo?: string 
    bar?: string 
} 

const reducers: Reducers = { 
    r1: (state: MyState, payload: string) => { 
    return {foo: payload} 
    } 
} 

Allerdings kann ich nicht bekommen dies zu kompilieren. Der Compilerfehler lautet:

Fehler TS2314: Generischer Typ 'Reducer' benötigt 2 Argument (e).

Was mache ich falsch?

+0

Was ist 'r1', ein Literaleigenschaftsname oder eine Variable? Und was ist dein Compilerfehler? – Sefe

+0

'r1' ist nur ein Eigenschaftenname. Ich möchte ein Objekt, das 'Reducers' implementiert, um beliebig viele Eigenschaften vom Typ 'Reducer' zu haben. Compilerfehler hinzugefügt. – harryg

Antwort

2

Sie benötigen eine generische Argumente an Ihre Reducers Schnittstelle zu übermitteln:

interface Reducers<S, P> { 
    [name: string]: Reducer<S, P> 
} 

const reducers: Reducers<MyState, string> = { 
    r1: (state: MyState, payload: string) => { 
    return {foo: payload} 
    } 
} 

Falls der Compiler Ihnen nicht erlauben, Ihre Reducer Methode inline zu definieren (ich damit einige Probleme hatte in der Vergangenheit), Sie kann den Wert extern definieren:

const r1Reducer: Reducer<MyState, string> = (state: MyState, payload: string) => { 
    return {foo: payload} 
} 

const reducers: Reducers<MyState, string> = { 
    r1: r1Reducer; 
} 
+0

Das sieht gut aus. Das Problem, das ich jetzt bekomme, ist, wenn ich versuche, auf eine der Eigenschaften zuzugreifen (zB 'reducers.r1 ({foo: 1}, 2)') Ich bekomme den Fehler 'Eigenschaft 'r1' existiert nicht am Typ 'Reduzierer '' – harryg

+0

Das liegt daran, dass die Reducers-Schnittstelle eine indizierte Schnittstelle ist und der Compiler die Eigenschaftennamen nicht im Voraus kennt. Sie sollten stattdessen Reduzierungen ['r1'] machen. – toskv

+0

ah ok, danke. Die andere Option besteht also darin, die Schnittstelleneigenschaften explizit zu definieren. Ich frage mich, ob meine Vorgehensweise in Ordnung ist, aber ich möchte es vermeiden, für jede von mir erstellte Instanz von Reduzierern spezifische Typen zu definieren. – harryg

1

Ihnen fehlen in Ihrem Code einige Generatentypen.

type Reducer<S, P> = (state: S, payload: P) => S 

interface Reducers<S, P> { 
    [name: string]: Reducer<S, P> 
} 

interface MyState { 
    foo?: string 
    bar?: string 
} 

const reducers: Reducers<MyState, string> = { 
    r1: (state: MyState, payload: string) => { 
    return { foo: payload } 
    } 
} 

Ohne sie kann der Compiler nicht die richtige Art von S und P generischen Typen bestimmen.

Verwandte Themen