Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
598 views
in Technique[技术] by (71.8m points)

typescript - 如何在Typescript中使用装饰器模式时使参数类型保持一致(How to make the type of parameters consistent while using decorator pattern in Typescript)

I have several functions that need to access a DB.

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

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);
};

I want to control a spinner before and after these process.

(我想在这些过程之前和之后控制微调器。)

The following decorator is my approach.

(下面的装饰器是我的方法。)

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');

However, this approach make the type hint useless:

(但是,这种方法使类型提示毫无用处:)

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

becomes

(变成)

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

Any suggestions to make it better?

(有什么建议可以使它更好吗?)

  ask by dacapo1142 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can fix the typings with a bit of generics:

(您可以使用一些泛型来修复类型:)

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, s2: string, n2: number) => void

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

Now decorator params are properly type checked (it will only accept the same set of parameters as a decorated function expects to get).

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

Function parameters type is extracted with Parameters utility

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

Playground

(操场)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...