可以创建一个通用类型来在其他类型中使用吗?

huangapple go评论53阅读模式
英文:

Is it possible to create a generic type to use in another types?

问题

I have this function:

function stackPlayer(stack) {

}

The stack parameter can only be one of the following:

  1. a function that takes req, res, next as arguments.
  2. a function that takes req, res, next as arguments, and returns a function that takes req, res, next as arguments.
  3. a function that takes req, res, next as arguments, and returns an array of functions that takes req, res, next as arguments.
  4. an array of functions that takes req, res, next as arguments.

Practical example:

// the following is allowed to be used as an argument:
(req, res, next) => {} // or
(req, res, next) => (req, res, next) => {} // or
(req, res, next) => [(req, res, next) => {}] // or
[(req, res, next) => {}]

In order to type the parameter of the function, I wrote the following, which looks quite complex to read and understand:

type Stack =
  | ((req: Request, res: Response, next: NextFunction) => {})
  | (
      (req: Request, res: Response, next: NextFunction) => (
        req: Request,
        res: Response,
        next: NextFunction
      ) => {}
    )
  | (
      (req: Request, res: Response, next: NextFunction) => {
        (req: Request, res: Response, next: NextFunction): void;
      }[]
    )
  | { (req: Request, res: Response, next: NextFunction): void }[];

function stackPlayer(stack: Stack) {

}

How can I simplify this long type? Can I create a generic type and use it for another type, for example:

type Smiddleware = <T = void>(req: Request, res: Response, next: NextFunction) => T;
type Stack = Smiddleware<void> | Smiddleware<Smiddleware> | Smiddleware<Smiddleware[]> | Smiddleware[];

This looks much better, but it's not valid, of course.

英文:

I have this function:

function stackPlayer(stack){

}

The stack parameter can only be one of the following:

  1. a function that takes req, res, next as arguments.
  2. a function that takes req, res, next as arguments, and returns a function that takes req, res, next as arguments.
  3. a function that takes req, res, next as arguments, and returns an array of functions that takes req, res, next as arguments.
  4. an array of functions that takes req, res, next as arguments.

Practical example:

// the following is allowed to used as an argument:
(req, res, next) =&gt; {} // or
(req, res, next) =&gt; (req, res, next) =&gt; {} // or
(req,res,sNext) =&gt; [(req,res,sNext)=&gt;{}] // or
[(req,res,sNext)=&gt;{}]

In order to type the parameter of the function, I wrote the following, which looks quite complex to read and understand:

type Stack =
  | ((req: Request, res: Response, next: NextFunction) =&gt; {})
  | ((
      req: Request,
      res: Response,
      next: NextFunction
    ) =&gt; (req: Request, res: Response, next: NextFunction) =&gt; {})
  | ((
      req: Request,
      res: Response,
      next: NextFunction
    ) =&gt; { (req: Request, res: Response, next: NextFunction): void }[])
  | { (req: Request, res: Response, next: NextFunction): void }[]

function stackPlayer(stack: Stack){

}

How can I simplify this long long type? can I create a generic type and use it for another type, ex:

type Smiddleware = &lt;T = void&gt;(req: Request, res: Response, next: NextFunction) =&gt; T
type Stack = Smiddleware&lt;void&gt; | Smiddleware&lt;Smiddleware&gt; | Smiddleware&lt;Smiddleware[]&gt; | Smiddleware[]

This looks much better, but it's of course not valid.

答案1

得分: 1

你可以将通用参数移到 Smiddleware 类型中,而不是在函数内部。

类似这样:

type Smiddleware<T> = (req: Request, res: Response, next: NextFunction) => T
type Stack = Smiddleware<{}> | Smiddleware<Smiddleware<{}>> | Smiddleware<Smiddleware<void>[]> | Smiddleware<void>[]

然后,你可以使用其他类型来代替 {}void,具体取决于函数的返回类型。

例如:

type Stack = Smiddleware<{}> | Smiddleware<number> | Smiddleware<Smiddleware<string>>;

关于你在注释中提出的问题,如果你想在不指定类型的情况下使用 Smiddleware,你可以为通用参数添加一个默认值:

type Smiddleware<T = void> = ... // 与之前相同
英文:

You can move the generic parameter to the Smiddleware type instead of the function inside.

Something like this:

type Smiddleware&lt;T&gt; = (req: Request, res: Response, next: NextFunction) =&gt; T
type Stack = Smiddleware&lt;{}&gt; | Smiddleware&lt;Smiddleware&lt;{}&gt;&gt; | Smiddleware&lt;Smiddleware&lt;void&gt;[]&gt; | Smiddleware&lt;void&gt;[]

Then you can use other type instead of {} or void, depending on what the function returns.

For example:

type Stack = Smiddleware&lt;{}&gt; | Smiddleware&lt;number&gt; | Smiddleware&lt;Smiddleware&lt;string&gt;&gt;;

Regarding your question on the comment, if you want to be able to use Smiddleware without specifying the type, you can add a default value for the generic parameter:

type Smiddleware&lt;T = void&gt; = ... // same as before 

huangapple
  • 本文由 发表于 2023年2月23日 19:17:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544097.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定