英文:
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:
- a function that takes 
req,res,nextas arguments. - a function that takes 
req,res,nextas arguments, and returns a function that takesreq,res,nextas arguments. - a function that takes 
req,res,nextas arguments, and returns an array of functions that takesreq,res,nextas arguments. - an array of functions that takes 
req,res,nextas 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:
- a function that takes 
req,res,nextas arguments. - a function that takes 
req,res,nextas arguments, and returns a function that takesreq,res,nextas arguments. - a function that takes 
req,res,nextas arguments, and returns an array of functions that takesreq,res,nextas arguments. - an array of functions that takes 
req,res,nextas arguments. 
Practical example:
// the following is allowed to used as an argument:
(req, res, next) => {} // or
(req, res, next) => (req, res, next) => {} // or
(req,res,sNext) => [(req,res,sNext)=>{}] // or
[(req,res,sNext)=>{}]
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 long type? can I create a generic type and use it for another type, ex:
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 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<T> = (req: Request, res: Response, next: NextFunction) => T
type Stack = Smiddleware<{}> | Smiddleware<Smiddleware<{}>> | Smiddleware<Smiddleware<void>[]> | Smiddleware<void>[]
Then you can use other type instead of {} or void, depending on what the function returns.
For example:
type Stack = Smiddleware<{}> | Smiddleware<number> | Smiddleware<Smiddleware<string>>;
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<T = void> = ... // same as before 
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论