[英]Typescript method of class generic type allows any
幾乎有一個小例外,我的約束似乎仍然允許任何例外。 誰能告訴我我在這里缺少什么。
用例:
class A {
public b(){}
public c:number = 0;
public d:any;
};
當前實施:
function methodOfClass<
T extends { new (...args: any[]): any; } & Function,
M extends (this:T, ...args:any[]) => any = {
[K in keyof T]: T[K] extends (this:T, ...args:any[]) => any
? T[K]
: never
}[keyof T]
>(ctor:T, method:M, args?:Parameters<M>) : ReturnType<M> {
return method.call(ctor, args ?? []);
}
const m0 = methodOfClass(A, A.prototype.b); // correct
const m1 = methodOfClass(A, A.prototype.c); // correct
const m2 = methodOfClass(A, A.prototype.d); // incorrect :-(
受此線程的啟發,我還管理了以下內容,但找不到合適的使用方法? 如何從 typescript 中的 class 創建不包括實例方法的類型?
type Methods<T> = Omit<T, {
[K in keyof T]: T[K] extends (this:T, ...args:any[]) => any
? never
: K
}[keyof T]>;
type M = Methods<A>; // correct
any
可以是Function
any
可以是任何東西,包括Function
。 您的methodOfClass
function 無法知道您打算將d
用作屬性。 d
成為 function 完全沒問題。
const a = new A();
a.d = () => "hello world"; // no error because `() => string` is assignable to `any`
換句話說,您看到的m2
的結果是預期的行為,它不是“不正確的”。 any
表示d
可以是 function 並且可以使用任何 arguments 調用它。 所以這也很好:
const m3 = methodOfClass(A, A.prototype.d, ["something", 999]);
顯然,這樣做存在巨大的運行時錯誤可能性。
這里唯一的解決方案是不要在 class 屬性上使用any
東西!
args
是可選的與any
的問題無關,我強烈建議您更改調用方法的方式以避免運行時錯誤。 如果 function 需要 arguments 但你只使用默認的[]
那么你會有問題。
(ctor: T, method: M, ...args: Parameters<M>): ReturnType<M> {
return method.call(ctor, ...args);
}
如果不需要 arguments,使用...
允許您不傳遞任何內容,但需要您傳遞所有必需的 arguments(作為單獨的參數傳遞給methodOfClass
而不是作為數組)。
class E {
public e(n: number): number {
return n + 1;
}
};
const m0 = methodOfClass(A, A.prototype.b); // this is still the same
console.log(m0); // undefined
const m3 = methodOfClass(E, E.prototype.e, 6); // but here we need a `number`
console.log(m3); // 7
const m4 = methodOfClass(E, E.prototype.e); // error because args missing
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.