I'm new to typescript and I'm not quite sure how to properly describe the return value type of a function. I have some abstract class and method
import { Request, Response, NextFunction } from 'express';
export interface RequestMiddleware {
(req: Request, res: Response, next: NextFunction): void
}
export abstract class ValidateRequest {
abstract checkData(params?: any[]): RequestMiddleware
}
And the class that inherits this abstract and implements the method
import { Request, Response, NextFunction } from 'express';
import { ValidateRequest, RequestMiddleware } from './contract/ValidateRequest';
class AuthSignUp extends ValidateRequest {
checkData(params?: any[]): RequestMiddleware {
return (req: Request, res: Response, next: NextFunction) => {
}
}
}
export default new AuthSignUp();
But I noticed that I can remove the arguments (or change the number of arguments) and typescript will not give errors
import { Request, Response, NextFunction } from 'express';
import { ValidateRequest, RequestMiddleware } from './contract/ValidateRequest';
class AuthSignUp extends ValidateRequest {
checkData(params?: any[]): RequestMiddleware {
return () => {}
}
}
export default new AuthSignUp();
How to do the correct typing, i.e., that the arguments of the return function checkData correspond to the described interface RequestMiddleware?
CodePudding user response:
TypeScript allows for function implementations with lower arity by design. For example:
type AddTwo = (a: number, b: number) => number;
const first: AddTwo = (a, b) => a b; // ok
const second: AddTwo = (a) => a; // ok
const third: AddTwo = () => 0; // ok
This is described in the Overloads and Callbacks section of the handbook:
Overloads and Callbacks
❌ Don't write separate overloads that differ only on callback arity:
/* WRONG */ declare function beforeAll(action: () => void, timeout?: number): void; declare function beforeAll( action: (done: DoneFn) => void, timeout?: number ): void;
✅ Do write a single overload using the maximum arity:
/* OK */ declare function beforeAll( action: (done: DoneFn) => void, timeout?: number ): void;
❔ Why: It's always legal for a callback to disregard a parameter, so there's no need for the shorter overload. Providing a shorter callback first allows incorrectly-typed functions to be passed in because they match the first overload.