带有泛型类型的打字稿包装函数

时间:2017-07-10 20:17:50

标签: typescript typescript-generics

如何在不更改Typescript中的泛型类型的情况下包装函数?

function x() {
  console.log('Original Function');
}

function wrapper<T extends Function>(func: T): T {
  // Typescript compiler error:
  // Type '() => void' is not assignable to type 'T'.
  return () => {
    console.log('Wrapped Function');
    func.call(null);
  }
}

const xWrapped = wrapper(x);
xWrapped(); // logged 'Wrapped Function' & 'Original Function'

2 个答案:

答案 0 :(得分:4)

这是保留参数并返回内部函数的类型而不依赖可变参数类型的一种选择。

import pandas as pd
import numpy as np
inputpath = '../Inputs/'
outputpath = '../Outputs/'

dtype_claim = { 'patent_id':'str',
                'sequence':'object', 
                'text':'str', 
               }
def runsort():
    print('Running claims_v2.csv')
    columns = ['patent_id', 'sequence', 'text']
    df = pd.read_csv(inputpath + 'claims.csv', dtype=dtype_claim, usecols=columns, encoding='utf-8', 
                        engine='python', error_bad_lines=False)
    df['sequence'] = pd.to_numeric(df['sequence'], errors='coerce')
    df['sequence'] = df['sequence'].fillna(-1)
    df['sequence'] = df['sequence'].astype('int64')
    df = df.sort_values(by=['patent_id', 'sequence'], ascending = (True, True))

    print('Exporting to CSV')
    df.to_csv(outputpath + 'claims_v2.csv', index = False)



runsort()

function x(message: string): void { console.log(`inner ${message}`); } export function wrapper<Args extends any[], Return>( operation: (...operationParameters: Args) => Return, ...parameters: Args ): Return { console.log(`outer `); return operation(...parameters); } x("abc"); wrapper(x, "xyz"); // output: // // inner abc // outer // inner xyz 调用wrapper时,TS编译器将其类型推断为x

如果您尝试呼叫function wrapper<[string], void>(operation: (operationParameters_0: string) => void, parameters_0: string): void,它将以优美的类型安全性失败:wrapper(x, 123)

答案 1 :(得分:1)

包装器函数应该接受一个函数并返回完全相同类型签名的函数。

Typescript无法知道传递的函数有多少参数或它返回的内容,并且您的函数隐式假设它需要0个参数(除此之外)并返回void。

目前还没有一种很好的方法可以在打字稿中保存功能签名。但是,对于可能解决此问题的更高版本,有一个新提案:https://github.com/Microsoft/TypeScript/issues/5453

现在你可以制作一个看起来像这样的通用包装器。

function wrapper<T extends (...args:any[])=>any>(func: T): T {
  return <T>((...args:any[]) => {
        console.log('Wrapped Function');
        return func(...args);
    });
}

根据Variadic类型的提议,这个函数可以像这样编写

function wrapper<...TArgs,TRet>(func:(...args:...TARGS)=>TRet) {
    return (...args:...TARGS) => {
        console.log("Wrapped function");
        return func(...args);
    }
}

请注意,这里的主要区别在于没有强制转换,上面的解决方案必须告诉编译器返回变量与输入变量的类型相同。但是对于可变参数类型,参数本身可以一般地键入。 (注意variadic类型目前不在typescript中,当包含do时,上述代码完全有可能出现语法错误)