我正在做一个有角度的项目,并且正在使用一个界面来定义模块的配置。该界面旨在将名称映射到对象,并且非常简单:
export interface NamedRoutes {
[routeName: string]: NamedRoute;
}
当我创建该接口的实例时,使用它时intellisense无法解析该实例的成员。例如:
const routes: NamedRoutes {
someRoute: {...}
};
const someRoute = routes. // no intellisense support here
据我所知,问题是,当编译器尝试回溯成员时,它会看到索引是字符串,因此可以允许任何内容,因此它无法建议实际存在的成员。
当我省略常数的键入时,intellisense能够建议正确的成员。据我所知,这是因为索引名随后被解释为符号,而不是字符串。缺点是,当我的API用户将对象传递给我的配置方法时,他们只会得到错误的编译器支持,在我们的项目中,该错误可能与对象创建完全不同。我认为,对于该API而言,这将是非常糟糕的用户体验。
我尝试使用Record<string, NamedRoute>
和<T extends string = string>
等不同的高级类型(用于索引类型)。
我希望我已经明确了我的问题是什么以及我要实现的目标。有合适的方法吗?
P.S .:对于我们的项目,也可以选择使用类型而不是接口。
答案 0 :(得分:1)
您可以为用户提供帮助功能,使他们可以使用它们来创建NamedRoutes
实例,而不是让他们使用NamedRoutes
注释。像这样:
// I like examples that compile, so here's something random:
interface NamedRoute {
whoKnows: string;
}
export interface NamedRoutes {
[routeName: string]: NamedRoute;
}
// helper function that just returns the input but makes sure it conforms to NamedRoutes
const asNamedRoutes = <T extends NamedRoutes>(t: T) => t;
// correct use
const routes = asNamedRoutes({
someRoute: { whoKnows: "blah" }
});
routes.someRoute // IntelliSense is here, yay!
// incorrect use so you still get early errors
const badRoutes = asNamedRoutes({
badRoute: { nobodyKnows: "whoops " } // error!
// type { nobodyKnows: string } is not assignable to NamedRoute
})
asNamedRoutes()
函数本质上与强迫人们比通常将对象传递给方法的方法相同,因此可以更早地发现错误。您可以采取一些措施来减少对NamedRoutes
的注释的可能性(使NamedRoutes
成为具有私有成员的类会产生这种效果),但这可能是过大了。
希望有帮助。祝你好运!