-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.js
132 lines (109 loc) · 3.55 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"use strict";
require("dotenv").config();
let http = require("http");
let express = require("express");
let app = require("./lib/my-router.js").Router();
let routes = require("./lib/routes.js");
// ⚠️ tsserver will tell you if an imported file doesn't exist
let doesntexist = require("./lib/doesntexist.js");
console.log(doesntexist);
if ("DEVELOPMENT" === process.env.ENV) {
// set special options
}
// if I type cannot be inferred by its use,
// it must be explicitly declared, like this:
/** @type User */
var user = {
// To see the linter in action,
// try renaming `given_name` to `first_name`.
given_name: "Jane",
family_name: "Doe",
favorite_book: "Harry Potter",
};
console.log(user);
/** @type {import('express').Handler} */
function allUsers(req, res) {
// this isn't explicitly typed here, but it will still be type checked
let user1 = {
given_name: "Orange",
family_name: "Fruit",
favorite_book: "Oh, The Places You'll Go!",
};
// ⚠️ tsserver knows that 'first_name' can't possibly exist
// Note: we never told tsserver that user1 was a user,
// it implied it from how we use it down below
console.log(user1.first_name);
// ⚠️ tsserver knows that a match can be null
console.log(user1.given_name.match(/foo/)[1]);
// The error message below applies to this, which is implicitly typed as a User
let user2 = {
given_name: "Banana",
favorite_movie: "Jurassic Park",
};
// ⚠️ See above to fix his
/**@type {Array<User>}*/
let result = [user1, user2];
res.json(result);
}
// pretend this is our login function
// Note: we have to type this explicitly because app.use can accept multiple
// function signatures and so the type cannot be inferred
/** @type {import('express').Handler} */
function requireUser(req, res, next) {
// ... verify req.headers["authorization"]
let user = {
given_name: "AJ",
family_name: "O'Neal",
favorite_movie: "Jurassic Park",
};
// ⚠️ To fix this error, make `favorite_book` optional,
// just like `favorite_movie` is optional.
// See ./types.js
req.user = user;
// ⚠️ To fix this error, go add req.admin as a boolean.
// See ./typings/express/index.d.ts
req.admin = true;
next();
}
app.use("/", requireUser);
app.get("/hello", routes.hello);
app.get("/users", allUsers);
// tsserver knows this function's type implicitly (unlike those above).
// Because it's used directly, inline, it doesn't need type annotation.
app.get("/implicitly-typed", function (req, res, next) {
// ⚠️ To fix this error, just check that the property exists
//if (req.user) {
console.log(req.user.given_name);
//}
// note:
next();
});
// ⚠️ To fix this error, go create a route for `goodbye`.
// See ./lib/routes.js
app.get("/goodbye", routes.goodbye);
// Express error handlers sometimes need a type annotation - but that's okay. They're rare.
app.use(
"/",
/** @type import('express').ErrorRequestHandler */
function (err, req, res, next) {
if (err.code) {
res.statusCode = err.status || 500;
res.json({ status: err.status, code: err.code, message: err.message });
return;
}
console.error("Unexpected Error:");
console.error(err);
res.statusCode = 500;
res.end("Internal Server Error");
}
);
let server = express().use("/", app);
if (require.main === module) {
let port = process.env.PORT || 3042;
let httpServer = http.createServer(server);
httpServer.listen(port, function () {
/* jshint validthis:true */
console.info("Listening on", httpServer.address());
});
}
module.exports = app;