[英]Typescript Array.isArray guard statement and return types on function
我有以下 function 可以按預期工作,如果將數組傳遞給第二個參數,則返回類型被正確鍵入為泛型 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
一旦我嘗試使用構建器 function 在 class 周圍引入包裝器 function 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
export function view<M = any, T = any>(View: V<M,T>) {
return {
build: (m: M | M[]) => builder(View, m),
};
}
您的view
包裝器有一個屬性build
,它接受一個參數M | M[]
M | M[]
。 推斷的返回類型是T | T[]
T | T[]
。 這里要注意的重要一點是build
只有一個調用簽名。 您期望 Typescript 知道調用build(M)
和build(M[])
是不同的,但您沒有告訴它。
可能有一種更簡潔的方法可以做到這一點,但您絕對可以通過重載build
function 來實現您想要的。
export function view<M = any, T = any>(View: V<M, T>) {
function build(m: M): T;
function build(m: M[]): T[];
function build(m: M| M[]): T | T[];
function build(m: M| M[]): T | T[] {
return builder(View, m);
}
return {
build
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.