Reputation: 11850
If i got it correct, we create do declare module "xyz" {
for the repo's not having interface?
I was going through this code in the repo where the author have created multiple interface inside declare module
declare module "express-rate-limit" {
import { Request, Response, NextFunction } from "express";
interface RateLimitReturnType {
(req: Request, res: Response, next: NextFunction): void;
}
interface Options {
max?: number;
message?: any;
headers?: boolean;
windowMs?: number;
store?: Store | any;
statusCode?: number;
skipFailedRequests?: boolean;
skipSuccessfulRequests?: boolean;
skip?(req?: Request, res?: Response): boolean;
onLimitReached?(req?: Request, res?: Response): void;
handler?(req: Request, res: Response, next?: NextFunction): void;
keyGenerator?(req: Request, res?: Response): string | Request["ip"];
}
interface Store {
hits: {
[key: string]: number;
};
resetAll(): void;
resetTime: number;
setInterval: NodeJS.Timeout;
resetKey(key: string | any): void;
decrement(key: string | any): void;
incr(key: string | any, cb: (err?: Error, hits?: number) => void): void;
}
export default function check(options?: Options): RateLimitReturnType;
}
And then this is how he is using it
const rateLimiter = RateLimit({
windowMs: RATE_LIMIT_TIME,
max: RATE_LIMIT_MAX
});
const publicRateLimiter = RateLimit({
windowMs: PUBLIC_RATE_LIMIT_TIME,
max: PUBLIC_RATE_LIMIT_MAX
});
const speedLimiter = slowDown({
windowMs: SPEED_LIMIT_TIME,
delayAfter: SPEED_LIMIT_COUNT,
delayMs: SPEED_LIMIT_DELAY
});
So I have three questions based on this..
and can someone explain me these lines
1.
export default function check(options?: Options): RateLimitReturnType;
interface RateLimitReturnType {
(req: Request, res: Response, next: NextFunction): void;
}
Upvotes: 0
Views: 742
Reputation: 5988
Why do we create multiple interface inside a declare module?
Because we want to group them into some place. Namespace or module is a perfect place to do this. In most of the cases, this is done automatically, so you shouldn't care about being them in one big file.
How does typescript knows which interface should the type match with?
When you create your package, you may include types into the package using types prop, like here:
{
"name": "@drag13/when-do",
"main": "./dist/index.min.js",
"types": "./dts/index.d.ts",
...
}
This will say to the TypeScript, where to get types for your code. But how does TS bind interface to the real code? By naming conventions!
Here is the example:
lib.d.ts
interface ICat {
name: string;
washed: boolean;
}
export function rename(cat: ICat, name: string): ICat;
export function wish(cat: ICat): ICat;
lib.js
export const rename = (cat, newName) => (cat.name = newName);
export const wash = (cat) => null;
Did you mentioned? I made a mistake in declarations and my second function named - wish
And here what we see in VsCode:
It thinks, that there is function wish :(. Will this be build? Yes, tsc will build it for you wihtout complains, but it will fail later. If you compile it and check the result, you will see something like here:
"use strict";
exports.__esModule = true;
var mylib_1 = require("mylib");
var cat = mylib_1.wish({ washed: false, name: 'jHon' });
And as far as our module have no wish function exported - it will fail at the runtime.
export default function check(options?: Options): RateLimitReturnType;
This says that your real module with code (js) will have default export with this signature. Again, it's only convention, and in real life, your code may have another default export or will not have default export at all.
Just like here:
library d.ts
type Options = {}
type RateLimitReturnType = {};
export default function check(options?: Options): RateLimitReturnType;
library js:
const check = () => 'wrong type';
export default check;
Fooled code:
Update:
About :
interface RateLimitReturnType { (req: Request, res: Response, next: NextFunction): void; }
This is just type declaration for the function. Example:
.d.ts
interface GreetTheCat {
(catName: string): string;
}
Upvotes: 2