Some of you will be familiar with TypeScript,
a language that adds static typing to JavaScript.
If you want to, you can use TypeScript
for our Next.js application.
Now, this step is optional;
it's only for those of you who
already know TypeScript.
In all the other videos I'll
use regular JavaScript,
simply because not everybody knows TypeScript,
and explaining that language would
require an entire separate course.
So if you don't know TypeScript, feel
free to skip the rest of this video.
But if you do want to use it in this project,
I'll now show you how to do that.
Let's stop the dev server,
because we're going to rename a few files.
Instead of "page.jsx",
we want to call this "page.tsx".
"tsx" is the extension for TypeScript files
that also contain JSX code.
Let's do the same for the layout file;
this one will be "layout.tsx".
The editor shows some errors at the moment,
but that's just because we haven't
configured this project yet.
We don't even have TypeScript as a dependency.
Now, the "next" command line tool
can set up everything for us.
We just need to start the server,
with "npm run dev" as usual.
You can see here that the "next"
command detected that
we're "trying to use TypeScript"
"but do not have the required packages installed",
and so it installed the dependencies
automatically.
It also "created a tsconfig.json file".
In fact, in our package.json
we now have 3 dev dependencies: "typescript",
and the typings for "node" and "react".
We also have two new files:
"next-env.d.ts", that contains some references,
and "tsconfig.json",
that's the main configuration file
used by the TypeScript compiler.
We can leave these files as they are.
Note however that, by default, it has
the "strict" option set to "false".
If you're a purist you may want
to change that to true,
but I'll leave it as it is.
So, the "next" command added TypeScript
support to our project,
after detecting that we had some "tsx" files.
And our application is still working,
even with TypeScript.
Now, in terms of code,
we don't really need to change
anything in this HomePage.
There is a way we could fully
type the React component,
by declaring it as a const of type "React.FC",
and then initializing it as an arrow function.
FC is short for FunctionComponent.
Although it's possible to do this,
it no longer seems to be the most
popular approach these days.
Even without explicit typings,
the TypeScript compiler can infer that
this function returns a "JSX.Element".
Which is pretty much all there
is to a React component.
Adding the "React.FC" annotation
doesn't have huge benefits,
while it makes the code a bit more complex.
So I'll leave this component as it is.
Now, if we look at "layout.tsx",
this component receives some props,
and at the moment this "children"
property could be anything.
So we may want to define an interface,
let's call it "LayoutProps",
where we specify that "children"
should be a "ReactNode",
that's a type we can import
from the "react" module,
and it represents effectively any JSX element.
Now we can use this interface
to annotate the "props" object.
And this way the compiler
knows what "children" is.
It will also know which properties
are available in this object,
in this case there's only this one.
But the compiler can check if we're
using the props correctly.
Now, as much as I like TypeScript,
and I would use it for any serious project,
one of the challenges with it is that
sometimes there's more than one
way to do the same thing.
For example, in the Next.js
documentation you'll see
the props object annotated like this,
rather than by defining a separate interface.
It's effectively the same thing.
I personally prefer having an interface at the top
where I can more easily see the props
accepted by this component.
Also, instead of an "interface",
some people prefer using "type" for everything,
including to describe the properties of an object.
Again, in practice this is pretty
much the same thing,
and which approach to choose is mostly
a matter of personal preference.
One feature I like to use is "import type",
for types that are only used by
the compiler at build time,
as opposed to functions or objects
that import JavaScript code used at runtime.
This is not usually necessary;
but I like the distinction.
Of course, you may have your own preferences.
But the important thing is that our
app now supports TypeScript.
Now, even though I'll use JavaScript
in the rest of the videos,
I'm also providing you with a TypeScript
version of this project.
If we take another look at the Github Repository,
it includes a "typescript" branch,
where you can again find all the code,
but written in TypeScript rather than JavaScript.
You can see that there are
"ts" and "tsx" files here.
About 90% of the code is the same anyway,
but from the next lecture onwards
you'll also find a link to a TypeScript Diff,
where you can see how I would type
function parameters for example,
or define an interface to describe some data.
So if you want to use TypeScript while
following along with the videos
by all means you can do that.