我有一个带有路由列表的枚举。
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'.
不幸的是,该错误并没有真正说明问题是“不可分配”以外的问题。我该如何修正我的代码或使用另一种策略来实现相同的目标?
答案 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中看到此代码。
这种方法是明确的,不需要像枚举(!)中那样指定冗余数字值。