对路由器使用泛型枚举

时间:2020-05-19 22:41:44

标签: typescript generics enums

我有一个带有路由列表的枚举。

enum ServerRoutes {
  WHISPER_SECRET = 0,
  SHOUT_SECRET = 1,
  SHOUT_SECRET_MULTIPLE_TIMES = 2
}

我想创建一个ServerRouter,它具有编译时保证可以处理所有路由。我想使用泛型来执行此操作,以便以后可以创建ClientRouter

type Router<T> = { [route in keyof T]: () => void }
type ServerRouter = Router<ServerRoutes>;

到目前为止一切顺利。上面的所有内容都可以编译。但是,当我尝试实际实现ServerRouter时,出现错误。这是生成错误的代码:

const serverRouter: ServerRouter = {
  WHISPER_SECRET: () => {},
  SHOUT_SECRET: () => {},
  SHOUT_SECRET_MULTIPLE_TIMES: () => {}
}

这是错误:

Type '{ WHISPER_SECRET: () => void; SHOUT_SECRET: () => void; SHOUT_SECRET_MULTIPLE_TIMES: () => void; }' is not assignable to type 'ServerRoutes'.

不幸的是,该错误并没有真正说明问题是“不可分配”以外的问题。我该如何修正我的代码或使用另一种策略来实现相同的目标?

2 个答案:

答案 0 :(得分:0)

引擎盖下的枚举创建了复杂的结构,正如here所述,它不太容易迭代。该结构如下所示:

(function (ServerRoutes) {
    ServerRoutes[ServerRoutes["WHISPER_SECRET"] = 0] = "WHISPER_SECRET";
    ServerRoutes[ServerRoutes["SHOUT_SECRET"] = 1] = "SHOUT_SECRET";
    ServerRoutes[ServerRoutes["SHOUT_SECRET_MULTIPLE_TIMES"] = 2] = "SHOUT_SECRET_MULTIPLE_TIMES";
})(ServerRoutes || (ServerRoutes = {}));

在您的情况下,请尝试使用类而不是枚举,它将可以正常工作。我创建了示例here

class ServerRoutes {
  WHISPER_SECRET = 0
  SHOUT_SECRET = 1
  SHOUT_SECRET_MULTIPLE_TIMES = 2
}

答案 1 :(得分:0)

您可以看到here并不是第一个想要对数组使用keyof的人,而且看来TypeScript中仍然没有一种干净的解决方案来获取所需的内容。

不过,或者,您也可以创建一个接口来指定serverRouter的合同,例如

type RouterFunction = () => void

interface IServerRouter {
  WHISPER_SECRET: RouterFunction
  SHOUT_SECRET: RouterFunction
  SHOUT_SECRET_MULTIPLE_TIMES: RouterFunction
}

const serverRouter: IServerRouter = {
  WHISPER_SECRET: () => {},
  SHOUT_SECRET: () => {},
  SHOUT_SECRET_MULTIPLE_TIMES: () => {}
}

您可以在此TypeScript Playground Link中看到此代码。

这种方法是明确的,不需要像枚举(!)中那样指定冗余数字值。