typescript 如何根据枚举获取回调的对象类型?

mbjcgjjk  于 2023-01-21  发布在  TypeScript
关注(0)|答案(1)|浏览(163)

假设您有以下TS代码:

enum stores {
  book,
  chapter,
  verse
}

const reducer = {
  [stores.book]: { a: 'string', b: 1 },
  [stores.chapter]: { a: 'string', c: 2 },
  [stores.verse]: { a: 'string', d: false }
}

function main ({
  storeName,
  getA
}:{
  storeName: stores,
  getA: (item: typeof reducer[stores]) => void
}) {
  const item = reducer[storeName]
  getA(item)
  return
}

main({storeName: stores.verse, getA(item) {
  item.a // only can get common a attribute, but
  item.d // can't get special for stores.verse attribute
}})

我应该怎么做才能让typescript根据storeName和reducer动态地理解getA中项目的类型?
在我的React-Redux应用程序rn工作。我想为多个Redux切片制作通用组件。组件内部的API只包含公共属性,所以它很好,工作正常,但我需要在一个 prop 函数中获得切片中对象的确切类型

svmlkihl

svmlkihl1#

编译器需要跟踪用于调用函数的stores的特定成员。这可以通过声明泛型类型参数S并使用它来键入storeName来实现。
作为storeName传递的值的类型将用于推断S的类型。参数item可以键入为typeof reducers[S]

function main<S extends stores>({
  storeName,
  getA,
}: {
  storeName: S;
  getA: (item: typeof reducer[S]) => void;
}) {
  const item = reducer[storeName];
  getA(item);
  return;
}

参数item的类型现在取决于作为storeName传递的枚举成员。

main({
  storeName: stores.verse,
  getA(item) {
    // ^? item: { a: string; d: boolean; }
    item.a;
    item.d;
  },
});

main({
  storeName: stores.book,
  getA(item) {
    // ^? item: { a: string; b: number; }
    item.a;
    item.b;
  },
});

Playground

相关问题