代码之家  ›  专栏  ›  技术社区  ›  laptou

TypeScript将交叉点类型映射到重载

  •  2
  • laptou  · 技术社区  · 7 年前

    我有一个类型,它是表示方法签名列表的类型的交集:

    type query =
        | ((query: getAuthorizationState) => AuthorizationState)
        | ((query: setTdlibParameters) => Ok)
        | ((query: checkDatabaseEncryptionKey) => Ok)
        | ((query: setAuthenticationPhoneNumber) => Ok)
        | ((query: resendAuthenticationCode) => Ok)
        | ((query: checkAuthenticationCode) => Ok)
        | ((query: checkAuthenticationPassword) => Ok)
        | ((query: requestAuthenticationPasswordRecovery) => Ok)
        | ((query: recoverAuthenticationPassword) => Ok)
        | ((query: checkAuthenticationBotToken) => Ok)
        | ((query: logOut) => Ok)
        | ((query: close) => Ok)
        | ((query: destroy) => Ok)
    // ...
    

    这适用于301行,旨在作为参数和结果之间的映射。然后,我创造了一系列的类型来表演一些体操,以改变 query 类型:

    type ParamDistribute<T> = T extends (q: infer U) => infer V ? U : never;
    type ReturnDistribute<T> = T extends (q: infer U) => infer V ? V : never;
    type QueryDistribute<T> = T extends (q: infer U) => infer V ? (q: U) => V | error | null : never;
    type PromiseDistribute<T> = T extends (q: infer U) => infer V ? (q: U) => Promise<V> : never;
    type FutureDistribute<T> = T extends (q: infer U) => infer V ? (q: U) => Future<Error, V> : never;
    
    export type Query = ParamDistribute<query>;
    export type QueryResult = ReturnDistribute<query>;
    export type QueryFunc = QueryDistribute<query>;
    export type QueryFuncPromise = PromiseDistribute<query>;
    export type QueryFuncFuture = FutureDistribute<query>;
    

    QueryFunc 查询 ,但所有返回类型都与相交 error (不是 Error ,但我有一个自定义接口)和 null . QueryFuncPromise 查询 ,但所有的退货类型都是承诺等。

    现在,我有一个类,它有一个实现这种类型签名的函数。我试着应用 查询 使用接口键入并使函数通用:

    interface TDClientFunctions
    {
        query: TDL.QueryFuncFuture;
    }
    
    export class TDClient extends EventEmitter implements TDClientFunctions
    {
        // ...
    
        public query<T extends TDL.Query, V extends TDL.QueryResult>(query: T): 
            Fluture.FutureInstance<TDL.error, V>
        {
            // ...
        }
    }
    

    但是,当我尝试使用该方法时,仍然没有得到正确的类型验证:

    enter image description here

    系统中只有一个接口 查询 符合我传递的参数的交点:

    export type testCallEmpty = {
       _: "testCallEmpty",
    }
    
    // ...
    
    type query = 
        // ...
        | ((query: testCallEmpty) => Ok)
        // ...
    

    那么,为什么返回类型不能解析为 Ok ? 为什么类型参数 V 没有正确推断?

    换句话说,我试图提供函数重载签名,而不是将它们作为重载编写,因为有300个,我的类将有多个方法遵循这种模式(因此 QueryFunc , 牢骚 , QueryFuncFuture 等等)。在TypeScript中可以这样做吗?

    0 回复  |  直到 7 年前
    推荐文章