如何在Typescript中使用装饰器模式时使参数类型保持一致

我有一些需要访问数据库的功能。

const dbProcess1 = (s1: string) => {
    console.log(`dbProcess1 is called with a param : ${s1}`)
};

const dbProcess2 = (s2: string,n2: number) => {
    console.log(`dbProcess2 is called with params : ${s2},${n2}`)
};

const dbProcess3 = (s1: string,s2: string,n2: number) => {
    dbProcess1(s1);
    dbProcess2(s2,n2);
};

我想在这些过程之前和之后控制微调器。 下面的装饰器是我的方法。

const withSpinner = (process: (...params: any[]) => void) => {
    return (...params: any[]) => {
        console.log('display spinner');
        process(...params);
        console.log('stop spinner');
    }
};

const dbProcess1WithSpinner = withSpinner(dbProcess1);
const dbProcess2WithSpinner = withSpinner(dbProcess2);
const dbProcess3WithSpinner = withSpinner(dbProcess3);

dbProcess1WithSpinner('p1');
dbProcess2WithSpinner('p2','42');
dbProcess3WithSpinner('p1','p2','42');

但是,这种方法使类型提示无用:

const dbProcess3: (s1: string,n2: number) => void

成为

const dbProcess3WithSpinner: (...params: any[]) => void

有什么建议可以改善它吗?

noa37688 回答:如何在Typescript中使用装饰器模式时使参数类型保持一致

您可以使用一些泛型来修正类型:

declare function dbProcess3(s1: string,s2: string,n2: number): void;

const withSpinner = <T extends (...args: any[]) => any>(process: T) => {
    return (...params: Parameters<T>) => {
        console.log('display spinner');
        process(...params);
        console.log('stop spinner');
    }
};

const dbProcess3WithSpinner = withSpinner(dbProcess3); // is now (s1: string,n2: number) => void

dbProcess3WithSpinner('p1','p2','42'); // error: Argument of type '"42"' is not assignable to parameter of type 'number'

现在装饰器参数已正确进行类型检查(它将仅接受装饰函数期望获得的相同参数集)。

使用Parameters实用程序提取功能参数类型

Playground

本文链接:https://www.f2er.com/2998946.html

大家都在问