Transcript
This transcript was autogenerated. To make changes, submit a PR.
You hi, my name is Daniel
for the Conf 42 I'll walk you through types those compile options.
If you'd like to discuss a little bit more, you can just scan the
QR code Andor connect with me via LinkedIn. I will be happy to answer more
questions. So types compiler rules, type risk compiler options
what it is about if we would like visit the technical documentation,
we'd see a bunch of rules and it's really like difficult to
walk through all of them. It requires lots of time and
attention. Our presentation is mostly about this part which is
highlighted in red. We'll also touch upon a
little bit of the compiler option from
different categories, but the strict rules are mostly around
in those highlighted red zone. Before like
few minutes back the way how it
was divided Andor in the documentation was a little
bit different, so we could explicitly see which are strict checks
which are for example interchecks. Now they kind of
compiler this and then they call it type checking, but those
rules are still the same, they just categorize it a little bit different.
So we are starting on the TS config.
I hope most of you know what TS config is.
This part of the TS config which we will be
talking about is of course in the compile options, and within
the compiler options you can set up
some extra checks to make your typescript
to be more strict or for certain rules we
will be talking about the first rule we'll touch upon.
We'll start slowly. It's not implicit Annie,
and we have a very first code
snippet sample function
which has a parameter and our implicit n is
disabled, or it's false, or it's not set up at
all, which by default it's false. And by the way, this is how the presentation
will start with each rule. On the top left corner
you will see the compiler option and in the middle you will see
the code we are talking about. But with no
implicit any actually types would pop
up as error that this parameter implicitly
has can any type. By the way, maybe some of you have
noticed, but this no implicit any flag has changed to
true. So to helps you guys
to map when what
is being shown. For example with the true it will be always see on
the screen that there is some kind of error or a warning at least.
So here we can quickly see the implicit sample
dont implicit whats can n type and we can quickly fix
this by adding string to hotspot.
Where was the problem? It was in the parameter and we
have added string. Those is also how we follow up with other examples to
hotspot which part of the code
was problematic and how we fix this next one.
Also related, no implicit this time
this code
as the first glance looks fine and maybe
even before preparing
those presentation I would also say, yeah, it's completely fine,
but there is something which
every now and then I have seen as my ide.
But let's first enable the no implicit disk and now
we can see what those
id is complaining about,
namely this implicitly Andor type.
Yeah, and this actually is a little bit confusing
because typing this might
be a bit counterintuitive for many of us. And for me,
for example, it also was I have to express,
but there are actually two ways to fix this in a way
that typescript will be satisfied as well
with the no implicit enabled,
the first option is to make an arrow
function, and that's
actually it, you don't have to do anything more.
The problem was here,
this was the hotspot I would say of the error, and we
could fix it like that. Okay, simple.
But there is another solution, maybe more intuitive some, I would say
for me it is because I can quickly see that this
is explicitly set to those total amount, which in
this example is the class. And in
that way we fix this error with setting this in
the parentheses to total amount.
No implicit returns. For returns follow the
similar logic as no implicit n and
those. So I have quite some rules to go
through, so I will just skip this. But as you follow
the first two examples, I'm pretty sure you can conclude what
it is about no increase override.
It's actually interesting one up.
I wasn't. Yes,
it opens up and
up. It didn't go no, it here
we are here maybe
in typescript, actually we don't,
it's not that intuitive or
javascript was of course slightly different Java,
but for Java guys they could quickly see whats they
would realize what it is about. For Javascript,
including myself, it might be something new
sometimes. So this flag tells us that if
we have a class and we
override whats class like here, so we have another class which extend
the class andor we override this, then basically
with this no implicit override,
we kind of cannot
do this if there is the keyword override. So if we
have overwrite set up and the flag is enabled and
we try to override
sorry, we basically, when we extend the class
and we override, we have to explicitly say that
we are overriding. So it's not like
implicitly set, it has to be the keyword.
We are getting back to the presentation now.
Unused locals it's about not unused local
variables. Once again I will move forward.
The name says everything. I would say
the same about no unused parameters
and allow unreachable code.
That's something which I would just copy paste what's
from documentation here
with this, like you don't have to do anything. By default it's undefined,
which means you will get a warning in your ide that
yeah, those is a code which is unreachable.
It's a small synthetic improvement, but still we don't want
words like that code aloe unused labels
and once again I will take a little bit from the
documentation. It's actually same
as aloe. Any tribal code id will give you a documentation,
but it's very rare that you will see it because in
javascript we don't tend to use libraries that much.
Maybe when you'll be working for object literals you might spot
this. But even if you'll forget about this Andor most of
probably you will about this compile option,
then by default you will get a warning. It will
still compile to Javascript, but you just get a warning.
Stricter note checks so that's one
of the reasons why I skipped this very simple flags simple
options because there are some
compile options which are more essential
I would say, for this presentation. Andor first of them is stricter null
checks. This code also
like without
this enabled, your id actually
wouldn't help you, I would say wouldn't tip you.
But more experienced or even middle experienced
developers could quickly know that okay,
those greeting whats a string? And now it's a null. So there
is something phishing definitely. And it is because if
you enable this we can quickly see that type null is
not as enabled type string. So that's
the first, let's say parasite stricter
compiler option from typescript we spot on
this part of the code which we fix this by adding
an extra type.
Yeah, of course writing to null might
be like a bad practice in general or in
most of the scenarios I would say. But from
the compiler options, if you are writing to Nordis, how you can fix
this? So we had the problem here and
we have based data strict
property initialization,
very basic example.
Many would say yeah, everything is fine.
I think quite some would say yeah, we are missing initialization
and if we will enable this
rule, then something will pop up here.
Little note, if you want to have to enable the
strict properties initialization, you have
to also enable strict null
tracks. Basically if you put the strict prepared initialization
to true, then you have
pop up from id that to have this working you need
to enable strict null checks. So they are working only both together.
I mean stricter project initialization requires strict null
checks. That's better to say.
So with those two enabled we can see that
property name has no initializer.
Andor the fix is basically very
trivial. We just need to initialize this. Those hotspot
was here. We fix this by initializing
string string functions type function
types. So it's slowly become interesting I hope.
Yes, this will be example go to
our ide at.
At first glance it looks completely fine,
but maybe some of you would already notice
that maybe string or number. String or number.
String or number. And here we are passing number and
we are putting this to lowercase. So watch
out whats will be happening. Okay, let's enable strict
function types to true. And we
have actually pop up from our ide.
It's complaining about the type okay,
which means that there is something wrong.
We will hotspot the place which we
have to make the fix. Let's say fix. So we just.
But the number here, okay,
I'm sorry, let me get back. We put those number
here Andor something different pops up now,
okay, which means that if
we follow those, as I said at the beginning,
there is some fishy. We pass number and two lowercase,
okay, and now we
can see that the type C
three compiler options helps us to avoid
bugs actually, because here if we pass those number,
even though here we are fine. Then thanks to
the case that we have strict function types to true types
shows us okay, here actually it doesn't look
good because it's one of those, okay, if we put
a number and to lowercase to lowercase
works only on strings,
okay. And with
strict function types to false,
it didn't say about this part anything about sample parameter
and it didn't even say about two lowercase,
which is actually the essential problem in this snippet
cost snippet. So I'm
highlighting, we have added the number Andor types
help us to actually spot where is the
real problem. And here I will have a very simple example.
Let me put examples.
Okay. I just open this for you guys.
It's a quite small example, okay Andor
let's disable this to false,
okay, here everything will be fine and
we will also wait, let me make it that way.
So I will remove it here and we see that
whats the error from the presentation and we
make it false now. Okay.
And takes time but
yes it works. And what's happening now we'll compile the typescript
file to Javascript it
did. What will happen now? Let's say we deployed
those part of the code somewhere and user
has clicked there was some kind of place to
put input and we try to but to
input to change the number to lowercase
and what will happen? Yes,
our users might have a bit unpleasant experience because it may throw
error and yeah,
most of a bit is not what we are looking for here.
It was a very nice example how typescript
can hotspot thanks
to the typing can hotspot actually bugs
here. The embedded
two lowercase typescript method actually
expects a string because
we will get back sorry,
not here.
So now we have the proper types, then we can see that okay, to lowercase
doesn't exist. So before deploying most of probably
to handle it somehow. Okay,
let me get back to the presentation.
Yes, this is what I said that were was a problem not spotted.
And now here we have all the hotspots.
So first type complain about this one. We had to change
here. The parameter was problematic, but at the end of the
day the lowercase, those lowercase,
it was the problem where it whats actually the but strict
bind call and apply this option.
I will skip. It's a
nice one, but we dont
tend to use bind call and apply that often after the
ecmascape six came. So if you
want to check it out, just take a look into
the documentation. It's explained quite well.
There no fall through cases in switch.
That's interesting. One we have switch
and cases. Our fall through case
in switch is disabled, but we enable this and what
happens, we have a warning.
Okay, and to
fix this we just basically need to add break because
type six spot us that. Okay, this case
ends without break. And here I also have
one little example because I think this one is much a
bit easier to follow if you see those real example hub.
Okay, so I will make it false.
Okay and I will remove
the break andor now
I will compiler TSC, six ts
and now we
can see even at odd, even though the number is zero. So it should
finish here. But there's four through
so it goes actually to one.
The log actually I
could put here maybe two. So it would be even and odd as more logic.
But I hope you guys realize
that it's just naming the
essential parties. This one and this
one. And now if we will compile
this one more time, or transcompile
to be more precise, then we can have
see only event which makes sense. We gave zero to
double check. We are in Javascript. Yes we
have break perfect.
Okay, so here was the
problem and we fixed it by adding break exact
optional property types, so becomes interesting.
It's not like stricter per se,
but there are also quite some types I will cover which are a bit like
a bonus. So this
one, it's getting
slowly advanced because
if we have the h with
question mark so which is like optional andor we put
it to number, then actually it's equivalent to number or undefined.
So those using this interface here
with these properties actually without
exact option. Now property types seems
to be fine, but actually it's not.
And here one more time for those compiler option,
we also need to enable strict nutrition before.
Once again if you will enable exec optional property
types first, the IDE will
guide you that you need to first enable strict note checks.
Okay, so we have this enabled and we can see that there is
little problem. Type undefined is not
assignable to type number, which means
that fix should be quite simple and it
indeed is. We have the
number and we can just add undefined.
So those function like you have something optional but
you really don't want to use it, you want to put undefined,
that's fine. So this is actually
more readable as
use unknown in catch variables.
Getting long right. This is can interesting one.
It's a very common scenario we use try and catch
of course, and if you enable
this flag then what will happen? Something weird
actually propertymessage does not exist on type unknown,
which means error.
Error is unknown.
I think it actually makes sense because
we don't know what kind of error will come up.
For now it's unknown. Or let's say for now it's unknown.
Sorry. To fix this we need to
put this in an if statement and actually if the
error is instance of error then
it will be gone saying in a
very simple words here we can see were was
the missing part and we have had whats if error instead
of error then I
believe that most of the code bases are without this.
While preparing the presentation I read that it might introduce
some, those might be some problems without
using the if with the
if, it's definitely more readable,
but how serious it
is if we won't put the if error is.
Actually, to be honest, I don't. I am not really sure if there's a
major risk for your code, but once again
if you would like to maybe discuss a little bit more, you can reach out
to me now. Always stricter.
Yes,
for that we have documentation. I think
now this part of protection will be quite a lot with documentation
always stricter is basically about the use stricter,
so it means you
actually should have it enabled, because ustrick
makes sure that your javascript is in a strict mode,
not in a sloppy mode. Sloppy mode is the code which sweep out
script and it follows bunch of rules making the
javascript less error prone, et cetera.
Strict enables
wide range of type checkings, some of them we covered,
right, for example stricter bind colon PI said
yeah, I mean we don't use that often bind colon apply
let's say anymore. So we skip those, but all the others
we actually talk about.
So you might think okay, you put strict to true and
all the typescript compiler option will be enabled
for you, so you won't introduce any bug. But actually
if you would get back to one of the very first slides,
you'd notice that okay, we had a bunch of doors, bunch of rules, and some
of them are
in type checking. Some of them actually are somewhat different andor
some of them we still didn't talk about.
So yeah,
I don't expect everyone will go through the whole documentation
to enable all types three compiler.
But just to be aware, if you put strict to true,
that's already progressed. But be aware
that there are many other rules we talked about and we have
still a little bit to talk about which
are not enabled. So with
stricter true your code won't be like ideal or absolutely
zero error prone.
So diving deeper imports
not used as values I
said I have documentation here for
some of those triggers. Actually it's not always it to find example, to be honest.
So for those part documentation
covered quite nicely by
default. If you have values
of types important never use
during complete
translation, it will drop this. If you want
to preserve this you can enable preserve, but I
don't recommend this because it can introduce some
side effects alternative.
If you really want to preserve them, then you can set
as error and then the typescript
compiler will show you that yeah, you have imported
some type or value, but it has been never used
here it's more like information with the default
remove you are fine. Skip lip check Andor
Skip default lip check skip lip check points
you to skip to default lip check Sorry Skip default leap check
points you to skip leap check sometimes
it might be case that the libraries which you're using
define two different types and
skip leap check will make
sure that the type c will not
check both of them. So actually that's a trade off between performance
and strict so if you want keep kind of like a
bit stricter rules. It's not strict per se,
but it's kind of strict. So if you want to make sure that it
will check dependency a
and b, if the types are correct, then you just keep it. If you
are looking for performance improvement then you can just put true. But basically
whenever you are facing this issue, you mostly read about your resolution
or overwrite. But this is also something
which typescript has force
consistent casing in file names.
I think it's self explanatory.
For example, your file will be
file manager in
upper camel case.
I think for this for example will
be very familiar for many people coming from react background
because the ecosystem and documentation kind
of guides you. But here if you
can make it,
you would like to make it more strict and have
the check automatic, then you can
also think about this. As you can see it's recommended
no implicit use stricter. Actually you
will never use this I believe,
but this rule and
the next one is just to be aware that there is something like that.
If you would like to. If for
some reason you don't want to have use strict when
emitting a module to a non es six target that's
actually important, then you can
put it to true. But 99
dont andor eleven 9% of you guys dont
need it and I'm not going to use that. But it reads
kind of too strict rules. I want to cover as much actually everything in
presentation, so I did include those, but you're not going to need it.
No. Typescript generic checks.
Once again,
this is good by default. This is set correctly by
default.
It protects you by default.
I cannot imagine that someone would like to
set it true, but for
you to be aware that for these kinds of scenarios,
typescript also protects you by default. That's nice.
Another flag. Here we
are in flags which actually are set
nicely corrective for us by
the TS config. Once again,
typescript protects you from this kind of scenario
when you have a type and you are trying to
create a variable with this type,
but with property inside which
is not defined. This type, please keep it.
Another one suppress implicit andor index
errors.
Here we
are also protected by default because for example,
imagine that we have can object and
we are trying to access foo, which actually
doesn't exist.
Actually you
can put this to true or put a TS ignore
on this, but that's a really bad thing, so please don't do it.
Once again, we can see that yet another scenario,
typescript protects us by default disable fine
line based system type acquisition.
That's a very small thing actually, but it's relatively new.
We have in typescript for one, since typescript
for one. For example, if you
have a jquery JS, then it will automatically
download the types for jquery from definitely typed.
So here I cannot come
up with a scenario when actually
I could think to use it because mostly I just install everyone
just install the package and it automatically gets everything.
But if for some reason you
have js file and you don't want those types to
be downloaded automatically, you can set this to true.
What can I say more here? Very niche,
that's a good word.
Now we are outside typescript world, but typescript
compiler options also has some rules
related to JavaScript. For example, allow JS by
default it's false. If you want to allow JS
modules to be imported in your typescript
project, you can set this to true. Another is check js.
So for example if you allow js then actually it would make sense whats
you also but checkjs to true because the check js will check if
those imported JavaScript modules are fine. So actually
you enable this only if allow JS is enabled.
Same for max node modules js depth by default
those is actually option about
how deep you can go
through node modules to import the JS module.
And you would of course enable this only when allowed.
JS is true because otherwise if you cannot allow js then what's those point to
put this one, if you cannot import js
files, the previous one
allow js and checkgrid you might use sometimes, but this one
I don't think so you will use it to offset, to be honest.
Now we have a couple of even
more advanced compiler
one moment, sorry,
no property, no property.
I'm not sure why the hyperlinks are working really bad. Sorry for that.
So what's happening here? We have interface
and we are assuming that
whatever is like here,
it's unknown. Whatever comes extra to the interface
then this is a
string, okay, so we say
yeah, for example string speed quality,
it's there, it's there, so no problem. But what's happening when there is string username
which is not here? And this is what
the compile option is about.
If you turn on the flag then okay, this is
continuation of the previous code, okay, you can see speed quality,
speed quality okay, and the interface is also here,
don't worry. So we can see that those property username comes from
an index signature, so it must be accessed with fusion. So if
it comes from index signature.
So if it's annoying the interface and you
want to put something
extra like property were,
then for the case you
can distinguish in the code that you are doing. So you
have to access it differently, namely like this.
In that scenario, while reviewing your code, you can actually
see that because of course when equivalent object in JavaScript we
can access the property via dot or
via array, okay, and put some value
because we can see that let's say those interface defines somewhat different
file whatever and we are going like this,
okay, then we see, okay, those two are defined,
but when we see something like that, then we can distinguish that
those is unknown for the interface.
So we can actually conclude this very quickly.
It's more like code quality
improvement, I would say a bit advanced,
very kind, sometimes niche, but this one actually might be used
sometimes. Now no unchecked indexed
access I will access it here because it's nearby.
Again we have interface name OS
inside. Again unknown properties are covered
by this index signature.
And what's happening here,
this is not declared Andor it's still as a string,
which kind of makes sense because this
is how we time. But let's think about the unknown keyword
with this flex enabled. Actually we would notice
that this one is stringed or undefined because
it was unknown, so it might be also undefined. Andor this
compile option will help to spot this
information.
Allow synthetic default imports I will look
like this synthetic default imports.
So here is when you are importing
a module and when the module doesn't have a default,
which you can import. So if the module doesn't have those port,
this flag will find this, but disable
size limit.
There are some memory related memory
things in typescript.
It's not related to your code, but it's actually related to testing
behind the scenes or under the hood. And if
you put this to true, which I wouldn't recommend,
then you might run in memory
related issues because otherwise,
which is by default there is some kind of size limit which typescript
allocates for the memory. So it's
a really low level thing. Guys, if you want to
read more about there are the official documentation,
there are two links basically you can also
check this one and at the end of the presentation
I will just to go very quickly through single page
application frameworks and how they integrate with strict we
have react which by
default has some rules enabled. Okay,
and look guys, you remember how many of rules we went through
it. Whats strict? So without taking this printation we think okay,
everything is fine. And we even have no fault through cases
in switch before it was so called a linter check.
We also have some force consistent casing in file names. I said
this might be familiar for people from react because this is actually enforced
by default. If you are working with types of CSX in
react, then yes,
then it kind of enforce you. I think if you generate
react code with Javascript, then it's also enabled the force
consistent casing in file name. So that's
a good thing for react. And we have also a couple of others,
few others. Okay,
you can generate probably create react
app. But some of the frameworks, if you add flagstrikes,
then they will generate a different ts config. I will show you very quickly
here in react, the strict doesn't work.
So we have those rules by default view
js two strict skip blitz
check and allow centering default imports.
When I checked on view JS three, it's basically the same
if you generate the view JS with typescript. There is just one
extra not related to our presentation compile
option angular.
Angular came with typescript, so we would expect quite a
lot actually here and that actually working in
angular you can generate your project with
Nginu and you can use the flag strict,
which would add some strict rules. Without this it won't add anything.
And here we have strict no implicit returns and no photo casing
switch. Those two actually are the all, let's say linters force
consistent casing in file names. It's also being added,
and in those default one it's not.
So here actually react
did better job, to be honest.
Sorry.
In addition to that angular access also it's
all compiled options. And when
you run this with strict, it also will add something
on top of this. So this is actually really strict
programming. Relatively strict programming
if compared to different single page application frameworks.
But let's say if you would forget but enable the flag
angular will ask you, hey, maybe you
want to get rid of some bugs andor while writing your code.
And that's the only one frameworks which will do it Svelter.
Svelter doesn't mean anything. We just go
through to config which is in
the package, which is in the hidden,
let's say. But if I open this, then I can only see stricter as false.
I think Svelte still has to do a little
bit more in the typescript ecosystem.
So while seeing this thing, I can see,
okay, svelte is maybe not the best place,
not the best framework to kick off with typescript
and here we have a comparison. Angular has
enabled on or off strict. I meant only the strict
per se. React and view also
can have it on the
linters. I name it Linter. It's according to those, let's say old
fashioned how to say, let's say the extra
stick rules. Angular has two react, one certain view,
zero to wrap up types helps
preventing bugs. It's not only Reddit
or Stag, overshore or any other source. Those is actually
scientific fact. So it
helps to. In this research it was about
15%, but for example, think it was TypeScript
2.0. So it was quite some time back.
And now imagine with a new typescript. And if you'd enable your
stricter rules, that's one and two, if you'd enable
all the strict rules, or at least half of them we went through
today, then this number can go up.
And this is what I actually really like saying, that you don't
need types because you are an expert. It's the same as you
saying you don't need tests because you don't write bug code
at the end, maybe a very little note.
I cannot imagine there were that many bugs at Airbnb,
but apparently they have made kind
of audit. If they introduce typescript,
then the bugs will be reduced by 38%
of the bugs could have been gone. It's a big number.
It's a big number. And I'm really curious if they enable the stricter
rules or even if they restrict it.
So we can maybe see that in the research they didn't. And here they did
some and we can see, kind of approximation,
how our code can be improved. That's it.
That's again the QR code. If you want to connect me, just hit
me up. I'm really happy to hear some feedback and
walk a little bit more in depth in some of them. Thank you so much.
It was a pleasure to give this talk.