Categories
Express JavaScript Nodejs

More About Routing with Express

Routing is the most important part of a back end application. Express allows us to route URLs to our route handler code easily.

In this article, we’ll look at how to create different kinds of routes with Express.

Handling All Requests

We can use the app.all method to handle all request methods. To use it, we can write something like the following:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.all('*', (req, res, next) => {  
  console.log('route called');  
  next();  
})

app.get('/', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

The app.all call above will be invoked when any method or URL is sent. It’ll log 'route called' and then call next to call the specific route handler for that route.

Non-Letter Symbols

Express can match routes with non-letter symbols. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/foo.bar', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when we make a GET request to foo.bar then we get hi .

Special Characters

Optional Character

If the ? is in a URL path, then it’s considered an optional character. For example, ab?c matches ac or abc .

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab?c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when we make a request to /ac or /abc , we get hi .

One or More Character

If a URL has a + sign, then it’ll match one or more of the character preceding it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab+c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when making a request to /abc , /abbc , /abbbc and so on, we’ll get hi .

Wildcard

The * in the URL is a wildcard character.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab\*c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then we put anything between ab and c in the URL and get the hi response.

Optional Character Group

A character group is optional if it’s surrounded by parentheses and has a ? after it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab(cd)?ef', (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));

Then when we go to /abcdef or /abef , we get hi .

Regular Expressions

We can also use regular expressions as route paths. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/a/, (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));

Then when we make a request to /a , we get hi .

To get hi when we make any request with path that ends with foo , we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/.\*foo$/, (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Route Parameters

We can designate parameters by writing a colon before the key name of the parameter.

For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/:name/:age', (req, res) => {  
  res.send(req.params);  
})

app.listen(3000, () => console.log('server started'));

Then we get the following response:

{"name":"Mary","age":"10"}

:name and :age are interpreted as route placeholders. req.params will use them as the keys without the colon. Then whatever is set in the place of the placeholders will be the corresponding values.

Route Handlers

The callback in the second argument of the app.get above are route handlers. The same can be done for POST, PUT and DELETE requests by replacing app.get with app.post , app.put and app.delete respectively.

We can chain multiple handlers together with the next function. For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/',  
  (req, res, next) => {  
    console.log('handler 1 called');  
    next()  
  },  
  (req, res) => {  
    console.log('handler 2 called');  
    res.send();  
  })

app.listen(3000, () => console.log('server started'));

Then we should see:

handler 1 called  
handler 2 called

in the console.log output.

We call the next function which originates from the route handler’s parameter to call the next route handler function.

Conclusion

Routing with Express is simple. We can use strings or regular expressions to specify our route paths.

Some characters in string paths like ? , +, or * are special characters for paths with optional characters or wildcards.

Placeholders for route parameters are specified by using a colon in front of the placeholder name.

We call next to chain multiple route handlers together.

Categories
Express JavaScript Nodejs

More About the Express Application Object

The core part of an Express app is the Application object. It’s the application itself.

In this article, we’ll look at the methods of the app object and what we can do with it.

Methods

app.disabled(name)

The method returns true if the given setting is disabled.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.disable('foo');

app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.disabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get:

{"fooDisabled":true}

since we called app.disable(‘foo’);

On the other hand, if we called app.enable(‘foo’); then we get:

{"fooDisabled":false}

app.enable(name)

We can use enable to set the setting with the given name to true .

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.enable('foo');

app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.disabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get:

{"fooDisabled":false}

since we called enable with 'foo' passed in.

app.enabled(name)

The enabled method returns if a setting with the given name is enabled. For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.enable('foo');
app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.enabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get {“fooDisabled”:true} since we called app.enable(‘foo’); .

app.engine(ext, callback)

We call the engine method to set the template engine that we use to render our HTML output.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('views', './views');

app.get('/', (req, res, next) => {  
  res.render('index', { people: ['geddy', 'neil', 'alex'] })  
})

app.engine('html', require('ejs').renderFile);  
app.set('view engine', 'ejs');  
app.listen(3000, () => console.log('server started'));

Then we can add our template to views/index.ejs as follows:

<%= people.join(", "); %>

and we get:

geddy, neil, alex

displayed.

The callback should have the parameters, path , options , and callback .

app.get(name)

We can use the get method to get the value of a setting with the given name.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo');
app.get('/', (req, res, next) => {  
  res.send(app.get('title'));  
})

app.listen(3000, () => console.log('server started'));

Then we get Foo displayed since we called:

app.set('title', 'Foo');

app.get(path, callback [, callback …])

The get method lets us pass in a route handler callback or a series of them to handle get requests with the given path .

It takes the following arguments:

  • path — it can be a string or regex representing paths or patterns of paths. The default is / .
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo')
app.get('/', (req, res, next) => {  
  res.send('GET request made');  
})
app.listen(3000, () => console.log('server started'));

app.listen(path, [callback])

It starts a UNIX socket and listens to connects on the given path.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo')app.get('/', (req, res, next) => {  
  res.send('hi');  
})

app.listen('/tmp/sock');

Then when the /tmp/sock socket isn’t in use, we can start our app by listening to this socket.

app.listen([port[, host[, backlog]][, callback])

This listen method listens for connects on the given host and port.

If the port is omitted or it’s 0, then the operating system will assign an arbitrary port for it to listen to.

We can pass the Express app object to the http.createServer to listen to connections as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const http = require('http');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.send('hi');  
})

http.createServer(app).listen(3000);

This lets us easily provide both an HTTP and HTTPS version of the app with the same code base.

app is actually a function so we can pass it into http.createServer as a callback.

app.listen() returns an http.Server object and it’s a convenience method for the following:

app.listen = function () {  
  const server = http.createServer(this)  
  return server.listen.apply(server, arguments)  
}

So we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const http = require('http');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.send('hi');  
})

app.listen = function () {  
  const server = http.createServer(this)  
  return server.listen.apply(server, arguments)  
}

app.listen(3000);

Conclusion

We can check is a setting is set to false with the disabled method.

To process GET requests, we can use the get method. It takes a route path and one or more route handler callbacks.

Finally, we have the listen method to listen for connections from UNIX sockets or given host and port. app can be passed into Node.js’ http.createServer method as a callback function since app is actually a function.

Categories
Express JavaScript Nodejs

Using Express Middleware

Middleware functions are functions that have access to the request and response objects, and the next function for call the next middleware.

In this article, we’ll look at what Express middleware does and how we can use them.

Characteristics of Middleware

Middleware functions can run any code, make changes to the request and response object, end the request-response cycle, and call the next middleware in the stack.

Application-Level Middleware

We can run middleware that are used when any routes are called by passing it to the app.use method as a callback.

If we want to a middleware function to be called only when a request of one request method is called, then we can pass it to the app.METHOD method as a callback. Where METHOD is get , post , put , delete , etc.

For example, we can write a middleware function and pass it into app.use to log the request method of a request as follows:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use((req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we should get GET logged when we make a GET request to / .

We can restrict the middleware function to be run only on GET requests and to the path / by writing:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.post('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we only see GET logged when we make GET requests to the / path.

Running a Series of Middleware Functions

We can use the next method to call the next middleware function in the series, so we can use it to chain middleware function calls together.

For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
);

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we see:

middleware 1 called  
middleware 2 called

from the console.log output of each middleware.

If we send a response in our middleware, then the next one won’t get called. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/',  
  (req, res, next) => {  
    next()  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/',  (req, res, next) => {  
  res.end();  
})

app.listen(3000, () => console.log('server started'));

Then we get the output ‘Second middleware’ when we make a request to / .

Our route handler in:

app.get('/', function (req, res, next) {  
  res.end();  
})

wasn’t called.

We can call next as follows:

next('route');

to go straight to our route handler, bypassing the other middleware functions down the line.

For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.listen(3000, () => console.log('server started'));

Then when we make a request to /0 , then we get 0 . Otherwise, we get ‘Second Middleware’ outputted.

Router Level Middleware

Router level middleware works the same way as app-level middleware, but they’re bound to the instance of the express.Router() instead of the express instance.

For example, we can use it as follows:

const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use((req, res, next) => {  
  req.requestTime = new Date();  
  next();  
})

router.get('/', (req, res, next) => {  
  res.json(req.requestTime);  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));

Then when we make a request to the / route we get back the timestamp as the output.

Chaining middlewares and skipping routes work the same way as app-level middleware. For example, we can write the following to chain middlewares as follows:

const express = require('express')  
const app = express()  
const router = express.Router();

app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
)

router.get('/', (req, res, next) => {  
  res.json();  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));

Then we see:

middleware 1 called  
middleware 2 called

from the console.log output of each route middleware.

We can use next('route') to skip to the route as follows:

const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

router.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.use('/', router);
app.listen(3000, () => console.log('server started'));

Then when we make a request to /0 , then we get 0 . Otherwise, we get ‘Second Middleware’ outputted.

Conclusion

Using Express middlewares is simple. We can either pass them into app.use to make the middleware run for all request methods, or app.METHOD to make them run for the given method.

We can call next to call the next middleware, and call next('route') to call the route handler directly from a middleware.

Everything applies to both route and app-level middleware, except that they bind to the express.Router() and express() respectively.

Categories
Express JavaScript Nodejs

Using Template Engines with Express

To render an HTML response with an Express route, we should return it as a template with the variable interpolated rather than return it directly as an HTML string.

Templates are convenient and we can use them in a much more flexible way than HTML strings.

In this article, we’ll look at how to set the template engine of our app, and returning HTML responses.

Choosing Template Engines

We can use popular template engines with Express, like Pug, Mustache, and EJS. The default for the Express application generator is Jade, but we can use the other ones listed as well.

To render template files, we can set the application settings. To set the templates folder, we can set the views property by writing the following:

app.set('views', './views')

It’ll set the templates folder to the views directory of our app.

Also, we can set the view engine we want to use by setting the view engine property as follows:

app.set('view engine', 'pug')

To install the template engine library, we can run something like the following:

npm install pug --save

The command above will install pug view engine for us to use.

Rendering Items with Template Engines

We can use the res.render method to render our variables to our templates.

First, we create the views folder to store our templates as we set the ./views folder to be our templates folder.

Since we chose to use Pug as our template engine, the template files should have the .pug extension.

Inside the views folder, create an index.pug and then put:

html  
  head  
    title= title  
  body  
    h1= message

The title= and h1= are our tags and title and message are keys in which Express will use to get the values from in the object that we’ll pass to res.render .

Then we can create index.js in the same level as the views folder and add:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', pageMessage: 'Hello there!' });  
})

app.listen(3000, () => console.log('server started'));

In the code above, we called res.render to render an HTML response. The object:

{ pageTitle: 'Hello', pageMessage: 'Hello there!' }

will be passed to our index.pug template.

title will be the title in:

html  
  head  
    title= pageTitle  
  body  
    h1= pageMessage

message will be replaced by the 'Hello there!' . Anything right of the tag and the equal sign will be replaced by the value with the key given above.

In other words, pageTitle and pageMessage properties’ values’ are the ones that’ll go in between the title and h1 tags respectively.

So we get

and the title of our page will be 'Hello' .

Pug Syntax

We can have dynamic expressions other than variables. Loops and conditional expressions are part of Pug.

HTML Tags

Other HTML tags can be used with Pug.

For example, a link can be written as follows:

a(href='http://medium.com') Medium

In the code above Medium goes between the a tags and href=’http://medium.com' is the href attribute and value respectively.

Loops

We can also write loops with Pug. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', pageMessages: ['Hi', 'Bye'] });  
})

app.listen(3000, () => console.log('server started'));

in index.js and:

html  
  head  
    title= pageTitle  
  body  
    ul  
      each pageMessage in pageMessages  
        li= pageMessage

in views/index.pug , then we would get:

Conditionals

We can also add conditional expressions to our Pug template. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', user: { type: 'member' }   });  
})  
app.listen(3000, () => console.log('server started'));

in index.js and:

html  
  head  
    title= pageTitle  
  body  
    if user.type === 'anonymous'  
      p User type is anonyomous  
    else if user.type === 'member'  
      p User type is member  
    else  
      p User type is admin

in views/index.pug , then we get:

'User type is member'

since user.type in res.render is set to 'member' .

Conclusion

Rendering HTML response is easy if we use a template engine to do it. We can pass in an object in the second argument of res.render to pass in values that we want to display in the template.

With template engines, we can include loops, conditionals, and variables to make displaying dynamic content a breeze.

Categories
JavaScript TypeScript

Introduction to TypeScript Data Types — Tuple, Enum, and Any

JavaScript, like any other programming language, has its own data structures and types. JavaScript has a few data types that we have to know about in order to build programs with it. Different pieces of data can be put together to build more complex data structures.

JavaScript is a loosely typed, or dynamically typed, language. This means that a variable that’s declared with one type can be converted to another type without explicitly converting the data to another type.

Variables can also contain any type at any time, depending on what’s assigned. With dynamically typed languages, it’s hard to determine the type that a variable has without logging it and we might assign data that we don’t want in the variable.

TypeScript rectifies these issues by letting us set fixed types for variables so that we’re sure of the types. In this article, we’ll look at the TypeScript data types that are exclusive to TypeScript. In this article, we will look at the tuple, enum, and any data types.

Tuple

A tuple is a comma-separated list of objects. We can have as many comma-separated items as we want. However, in reality, we probably shouldn’t have more than 10 comma-separated items in a type. In TypeScript, we can declare a variable with the type by using brackets, with the type names separated by commas inside. This means that each entry in a tuple will have the type that’s set when we declared the tuple variable. For example, we can write:

let x: [string, number, boolean] = ['hello', 1, true];  
console.log(x);

Then we get:

["hello", 1, true]

A tuple is just an array that has fixed types of each entry. If we put the type that’s different than what we have specified in the position when we declared it, then we get an error. For example, if we have:

let x: [string, number, boolean] = [2, 1, true];  
console.log(x);

Then we get the “Type ‘number’ is not assignable to type ‘string’.” error, and the program won’t run. We can access an entry in tuple like we do with arrays since they’re just arrays with fixed types for each entry. For example, we can write the following code:

let x: [string, number, boolean] = ['hello', 1, true];  
console.log(x);  
console.log(x[0]);  
console.log(x[1]);  
console.log(x[2]);

Then we get:

hello  
1  
true

Likewise, the destructuring assignment operator also works as expected like any other arrays. For example, we can write:

const x: [string, number, boolean] = ['hello', 1, true];  
const [str, num, bool] = x;  
console.log(x);  
console.log(str);  
console.log(num);  
console.log(bool);

Then we get the same output as before. We can also put non-primitive objects inside tuple objects. For example, we can have an instance of a class that we created like in the following code:

class Person{  
  name: string;  
  constructor(name: string){  
    this.name = name;  
  }  
}  
const x: [string, number, boolean, Person] = ['hello', 1, true, new Person('Jane')];  
const [str, num, bool, person] = x;  
console.log(x);  
console.log(str);  
console.log(num);  
console.log(bool);  
console.log(person);

Then we get the following:

hello  
1  
true  
Person {name: "Jane"}

from the console.log output.

Enum

TypeScript has an enum type that’s not available in JavaScript. An enum type is a data type that has a set named values called elements, members, enumeral or enumerator of the type. They’re identifiers that act like constants in the language. In TypeScript, an enum has a corresponding index associated with it. The members start with the index 0 by default, but it can be changed to start at any index we like and the subsequent members will have indexes that increment from that starting number instead. For example, we can write the following code to define a simple enum in TypeScript:

enum Fruit { Orange, Apple, Grape };

Then we can access a member of an enum like with the following code:

enum Fruit { Orange, Apple, Grape };  
console.log(Fruit.Orange);

Then console.log from the code above should get us 0 since we didn’t specify a starting index for the enum. We can specify the starting index of an enum with something like in the following code:

enum Fruit { Orange = 1, Apple, Grape };  
console.log(Fruit.Orange);  
console.log(Fruit.Apple);  
console.log(Fruit.Grape);

Then we get the following logged from each console.log statement in order:

1  
2  
3

We can specify the same index for each member, but it wouldn’t be very useful:

enum Fruit { Orange = 1, Apple = 1, Grape };  
console.log(Fruit.Orange);  
console.log(Fruit.Apple);  
console.log(Fruit.Grape);

Then we get:

1  
1  
2

from the console.log. As we can see, we specify the index pretty much however we want to change it. We can even have negative indexes:

enum Fruit { Orange = -1, Apple, Grape };  
console.log(Fruit.Orange);  
console.log(Fruit.Apple);  
console.log(Fruit.Grape);

Then we get:

-1  
0  
1

from the console.log . To get an enum member by its index, we can just use the bracket notation like we access array entries by its index. For example, we can write the following code:

enum Fruit { Orange, Apple, Grape };  
console.log(Fruit[0]);  
console.log(Fruit[1]);  
console.log(Fruit[2]);

Then we get:

Orange  
Apple  
Grape

Any

In TypeScript, the any type means that we can assign anything to the variable that’s been declared with the type any. It’s no different from assigning anything as we do with variables in JavaScript. This lets us adopt JavaScript slowly to TypeScript, and also allows us to use dynamic objects like dictionaries. It also lets us use variables that we don’t know the type of like members from third-party library modules. We can assign anything to a variable with the any type and not get any errors. For example, we can declare and use a variable with the any type like in the code below:

let x: any = 1;  
console.log(x);  
x = 'string';  
console.log(x);

If we run the code above, then we get the following console.log value:

1  
string

The any type if also handy for declaring other data types like arrays. If we declare an array with the any type, then we can put data of any type as entries in our declared array. We can declare an array with any type like in the following code:

let anyList: any[] = [1, true, "abc"];  
console.log(anyList);

Then we get:

[1, true, "abc"]

from the console.log. TypeScript has an Object type which corresponds to the Object object in JavaScript. Therefore, it can’t be used like the any type. The Object type has its own methods like toString, hasOwnProperty, etc., and it’s nothing like the any type, which actually means that the variable can be assigned anything. For example, if we write the following:

let x: Object = 2;  
x.toFixed();

We would get the error “Property ‘toFixed’ does not exist on type ‘Object’.”. However, we can write the following code:

let x: Object = 2;  
console.log(x.hasOwnProperty('foo'));

As we can see, the Object type has a hasOwnProperty property method, which is what the Object object in JavaScript has.

A tuple is a comma-separated list of objects. We can have as many comma-separated items as we want. It’s just a JavaScript array with fixed types for each entry. TypeScript has an enum type that’s not available in JavaScript. An enum type is a data type that has a set named values called elements, members, enumeral or enumerator of the type.

They’re identifiers that act like constants in the language. Each enum member has an index, which can be set arbitrarily. We can also get the member name from its index with the bracket notation like how we get an array entry by its index.

The any type lets us assign anything to the variable that’s been declared with the type any . It’s no different from assigning anything as we do with variables in JavaScript.