网站搜索

如何在 TypeScript 中定义一个具有任意数量某种类型属性的接口


我想定义一个接口,该接口具有任意属性,并且这些属性的类型始终相同。例如。

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

interface Reducers {
  [name: string]: Reducer
}

然后像这样使用它:

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

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

然而我无法让它编译。编译器错误是:

错误 TS2314:泛型类型 'Reducer' 需要 2 个类型参数。

我哪里做错了?

答案#1

你需要将你的通用参数传递给你的 Reducers 接口:

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

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

如果编译器不允许你内联定义你的 Reducer 方法(我过去在这方面遇到过一些麻烦),你可以在外部定义该值:

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

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

答案#2

你的代码中缺少一些泛型类型标注。

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 }
  }
}

没有它们,编译器无法确定 S 和 P 泛型类型的正确类型。