簡體   English   中英

Typescript 方法的 class 泛型類型允許任何

[英]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

Typescript 游樂場鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM