【发布时间】:2021-03-26 06:25:01
【问题描述】:
我有以下函数按预期工作,如果将数组传递给第二个参数,则返回类型被正确键入为泛型 T 的数组。
type V<M, T> = { new (model: M): T };
interface GenericBuilder {
<M = any, T = any>(View: V<M, T>, m: M): T;
<M = any, T = any>(View: V<M, T>, m: M[]): Array<T>;
<M = any, T = any>(View: V<M, T>, m: M | Array<M>): T | T[];
}
export const builder: GenericBuilder = <M = any, T = any>(
View: ViewClass<M, T>,
m: M | Array<M>
) => (Array.isArray(m) ? m.map((l) => new View(l)) : new View(m));
const model = { x: 2 };
class MyView {
model: any;
constructor(model) { this.model = model }
get y() {
return this.model.x * 2;
}
};
const result = builder(V, model);
assert(result.y == 2); // passes tsc
const list = builder(V, [model]);
assert(list.map(r => r.y) == [2]); // passes tsc
一旦我尝试使用构建器函数在类周围引入包装函数,类型就会退回到 T | 的实现。 T[] 而不是接口中提供的覆盖。
export function view<M = any, T = any>(View: V<M,T>, T>) {
return {
build: (m: M | M[]) => builder(View, m),
};
}
const Wrapped = view(MyView)
Wrapped.build(model).y // fails tsc
Wrapped.build([model]).map(r => r.y) // fails tsc
【问题讨论】:
标签: typescript typescript-typings typescript-generics