我想使用泛型来减少维护,以及维护Typescript类型时出错的可能性。
我有一个名为loadValues
的函数,该函数通过以下示例接口接收一个对象:
interface DashboardPreload: {
studentNames: Observable<string[]>,
seatNumbers: Observable<number[]>
}
并返回具有以下非常相似的接口的对象。请注意,它具有相同的键,并且键具有相同的值,除了在DashboardPreload中,它包装在Observable中:
interface DashboardState: {
studentNames: string[],
seatNumbers: number[]
}
因此指定类型如下:
function loadValues(preload: DashboardPreload): DashboardState {
// ...
}
要在各个组件之间重用loadValue
函数,我更改了签名以允许使用泛型:
loadValues<A, B>(preload: A): B {
// ...
}
state = loadValues<DashboardState, DashboardPreload>(toPreload);
// another component would then do
interface UserDetailPreload: {
name: Observable<string>;
address: Observable<string>;
}
interface UserDetailState: {
name: string;
address: string;
}
otherState = loadValues<UserDetailState, UserDetailPreload>(otherValuesToPreload);
但是我仍然想取得巨大的胜利。我的输入和输出对象
为避免必须维护非常相似的类型,如果泛型可以指定输入和输出类型之间的上述关系,那就太好了。我只想提供一个通用参数(例如输出),然后以一种可以输入输入和输出的方式编写签名:
// How should this signature look?
function loadValues<P>(preload: ?): P {
// ...
}
state = loadValues<DashboardState>(toPreload);
这可能吗?函数签名的外观如何(请注意,我并不是在问函数的逻辑,而是在问如何做泛型)。
但尚未找到解决方案。
答案 0 :(得分:1)
您可以添加如下所示的预加载类型:
type Preload<T> = {
[P in keyof T]: Observable<T[P]>;
};
function loadValues<P>(preload: Preload<P>): P {
// ...
}
state = loadValues<DashboardState>(toPreload);
答案 1 :(得分:0)
我不确定我是否理解您要实现的目标,因此这可能无法给出完整的答案,但是也许可以将您推向正确的方向。
如果您也将preload
参数的类型设为通用,则typescript应该能够推断出通用返回类型。您需要为此引入一个新的通用接口。
因此,您的函数签名应如下所示:
function loadValues<P>(preload: PreloadState<P>): P {
// ...
}
interface PreloadState<P> { }
当您像这样使用它时
var preload: PreloadState<DashboardState> = { .. };
var result = loadValues(preload);
result
的类型将正确地推断为DashboardState
类型。