Check also my website! (Currently only in Polish): https://bstefaniak.pl/blog/co-nowego-w-typescript-5-5
Howdy!
Not so long ago the new Typescript officially came out, specifically version 5.5, which brought some really cool fiches, which are presented in this post. Most of them happen underneath, without our interference, but I think they are worth knowing about ;)
Enjoy reading!
1. Better type inference
As you can see below, we create our trailerParkBoys object array, to which we assign some data.
Next up is the getTrailerParkBoy function, which takes an array of strings names. Then we do an operation on the names array; we map and filter all the elements that are "undefined ‘, so there shouldn't be any ’undefined ” element in our boys array anymore right?
Inference in TS below 5.5
Well, that's exactly in TS under 5.5 (the version in the screenshot is 5.4.5) that's not true 😕.
You can see this in the following lines, where we try to call the "action ” method on every element in the boys array, because for TS, the boy element may still be undefined (even though we filtered out all undefined elements beforehand!).
Improving type inference in TS 5.5.
But here's where Typescript 5.5 goes all in white. 😎
Now Typescript no longer screams about a possibly undefined element, now the type is correctly deduced and we can execute the boy.action() method without any problems.
Why is this so?
Typescript 5.5 now automatically creates a “guard check” for itself in methods such as .filter, i.e. a check to make sure that the element we have in mind is of the correct type, and not (in this case) undefined.
As in the screenshot below, depending on the value of true or false of the condition occurring, our element is the expected type (in the case of true) or something else, in the case of false; in our example it's “undefined”.
The value true or false results from the result of the check that takes place underneath (and looks like the commented out isTrailerParkBoy function in the screenshot below)
const isSpecifiedType(value: WantedType | undefined): value is WantedType => ....
(... is ...Type expects boolean)
NOTE only works when we directly give “undefined” as a possible type
Conditions when it works!
- the function does not have an explicit type return or direct type assignment.
- The function contains only one return statement and no implicit returns.
- The function does not modify its parameter.
- the function returns an expression of type boolean, which is related to the refinement of the parameter type.
An example where this does not work:
function getClassroomAverage(students: string[], allScores: Map<string, number>) {
const studentScores = students
.map(student => allScores.get(student))
.filter(score => !!score);
return studentScores.reduce((a, b) => a + b) / studentScores.length;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// error: object is possibly 'undefined'.
}
Because the !!score condition in the .filter method can be false in the case of null, undefined (and indeed undesirable values), but so will be false when score = 0
2. Type Narrowing
Many times it has happened to you that all signs on heaven and earth indicated that some object NEWLY has a given key, but in fact the editor was spilling errors left and right screaming that MAAN, THERE IS NO SUCH KEY?
To me, quite often, that amounted to fiddling with the code, adding guards or projecting types to make TS realize how wrong he was.
Fortunately, that's just history now 😎
TS older than 5.5 did not properly narrow the type when getting to the value in the object
As you can see below in Typescript older than 5.5, despite trying to get into the value of a obj record after checking that the value exists and is a string Typescript still threw the error Object is of type 'unknown'.
Until now, we had to deal with this problem in a different way, for example, by casting the value manually ```as
TYPE''
TS 5.5 correctly deduces the type
As you can see below in Typescript 5.5 this has been corrected, so that after checking the value {% raw %}obj[key]
we know that it exists and is of type string therefore we are able to get to it without any problem using obj[key]
and call the string method toUpperCase()
.
3. Type checking in REGEXP
Now RegExps are validated! This is great news, because now every redundant or dropped parenthesis will throw us an error. (aaa, for the rest, no one writes regexps by hand anyway 👀)
4. JSDoc type imports
I suspect that JSDoc is somehow not incredibly often used due to the fact that Typescript itself “documents” the code we write. Nevertheless, I subjectively like this type of “summary” of what a function, method, class does and what it is responsible for.
To shore up; until now we were limited to primitive types, type rewriting, or trying to import it from some modules.
Before TypeScript 5.5, when you tried to import types from external files in JSDoc in JavaScript files, you often got runtime (execution time) errors. This was because TypeScript treated these imports as if they were actual module imports, leading to problems when in fact only types were imported, not entire implementations.
In addition, Typescript, due to its limited static type parsing capabilities, could not accurately recognize types from external files.
In TS 5.5, we can use the @import keyword to import our type as we normally do.
5. configDir variable in tsconfigs
An improvement mostly useful in monorepo projects, but worth knowing about. We can have a base tsconfig file that we share in several different places. Well, that's all cool, but what if you need to recompile TS to a particular folder, for example? Then a little problem begins, because even though our “outDir” will spit out the resulting files to the /dist folder (conventionally named dist), but where our base file is located, not the one that extends it.
With the help of the new variable configDir, which makes this path to be with respect to the file it extends, not the base file.
That is, in the case in the screenshot, it will compile our TS files to the /front-dir/dist folder (rather than /dist).
We use this in the same way as the variables in the template string: `“${configDir}/folder_name”
; just like in the screengrab below. ;)
Summary
These are, in my opinion, the most important items that will make your work much more enjoyable.
I encourage you to bite into the other tidbits in this issue of TS 🤓.
Until the next one!
~ Bartek
Check also my website! (Currently only in Polish): https://bstefaniak.pl/blog/co-nowego-w-typescript-5-5
Source material:.
Linkedin: https://www.linkedin.com/in/bartosz-stefaniak-a82727222/
Top comments (0)