声明一个属性不仅是一个类型的“ keyof”,而且是一个东西的数组

时间:2019-03-07 05:05:48

标签: typescript

我具有以下功能:

export function listMutations<S, M extends Model>(postfix: keyof S): MutationTree<S> {
  return {
    ADD(state, payload) {
      state[postfix].push(payload.value)
    },
    CHANGED(state, payload) {},
    REMOVED(state, payload) {},
    RELATIONSHIP_ADDED(state, payload) {},
    RELATIONSHIP_REMOVED(state, payload) {},
  }
}

其中S代表特定的“状态树”,而M是给定的数据模型。 “模型”是指适合状态树的模型。例如,假设状态树看起来像这样:

export interface StateTree<M> {
  all: M[],
  byId: ...
}

传递到函数中的postfix值确定该属性是“全部”还是其他,但是假定给定postfix属性,则:

  1. postfix是状态树的 keyof
  2. 并且postfix属性的值是M的数组

我已经为第一个条件输入了内容,但是因为这种输入不能告诉类型系统该值始终是数组,所以我在.push()调用中遇到了类型错误。

然后我查看了这个问题以供参考:keyof-that-is-also-of-type-t。这有所帮助,并导致了这种尝试:

export type ListPropertyCandidates<T> = Pick<T, { [K in keyof T]: T[K] extends Model[] ? K : never }[keyof T]>

export function listMutations<T>(postfix: keyof ListPropertyCandidates<T>): MutationTree<T> {
  return {
    ADD(state, payload) {
      state[postfix].push(payload.value)
    },
    CHANGED(state, payload) {},
    REMOVED(state, payload) {},
    RELATIONSHIP_ADDED(state, payload) {},
    RELATIONSHIP_REMOVED(state, payload) {},
  }
}

我认为 ListPropertyCandidates 中包含T[K] extends Model[]可能会带我到那里,但打字错误仍然存​​在,因为它不能像往常一样识别state[postfix]数组。

有人有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我认为不定义state本身的类型是不可能的

function listMutations<S, M extends Model>(postfix: keyof S): MutationTree<S> {
  return {
    ADD(state: Record<keyof S, M[]>, payload: {value: M}) {
      state[postfix].push(payload.value);
    },
    ...
  }
}