1. Create a type checking function
interface IDog{
name: string;
age: number;
kidFriendly: boolean;
}
interface ICat{
name: string;
age: number;
activityLevel: number;
}
type Animal = IDog | ICat;
/** Is the animal a dog ? */
const isDog = (animal: Animal) : animal is IDog => (animal as IDog).kidFriendly !== undefined;
if(isDog(animal)){
console.log(animal.kidFriendly);
}
More information here:
2. Set all properties of an interface to optional
interface IDog{
name: string;
age: number;
kidFriendly: boolean;
}
const dog : Partial<IDog> = {
name: "Rex"
}
3. Get the type of the parameters of a function
const walkDog = (dogName: string, distance: number) => { /** ... */ }
const params: Parameters<typeof walkDog> = ["Rex", 48];
4. Use Setters and Getters
Setters and Getters also exist in plain JavaScript. Still, they are very useful in TypeScript (and other languages).
class Dog{
private _name: string = "";
get name(): string{
return this._name;
}
/** Check the length of the name before setting it **/
set name(newName: string){
if(newName.length < 8) {
throw new Error(`The dog's name needs at least 8 charachters`)
}
this._name = newName;
}
}
5. Optional chaining
Optional chaining has recently been added to JavaScript (ECMAScript 2020).
let cat?: ICat;
/** With optional chaining **/
let animal = cat?.fur.length;
/** Without optional chaining **/
let cat = cat === null || cat === undefined ? undefined : car.fur.length;
Top comments (13)
How does the isDog function work since .type is not a valid property? And how does JS know to set the private property .name in the setter instead of calling the setter again?
My guess would be that the example is not complete.
You could create an enum like
and adjust the Interfaces by creating animal as parentinterface:
I guess you're right, I also didn't understand how it worked, and I noticed how much code is needed just to determine if an animal is an IDog or an ICat ...
This seems so basic, but no, we need to write something like:
I don't even understand the "animal is Dog" construct before the arrow, what is that? ... and now it seems that in fact we also have to add an enum to make it work :-)
I can't believe that we need this much boilerplate for something so trivial ... why doesn't TS simply let us write
const isDog = animal is IDog;
or something like that?The concept is called typeguard and its basicly that you telling TS a condition under which an animal will be a dog since TS can't infer it sometimes by itself.
You could modify the example by writing something like:
if you then have something beeing typed as animal a simple if-statement would be enough to determine the type
Thanks, I vaguely remember type guards ... such a complex beast, Typescript, I've done one toy project with it, and yes you can produce some pretty elegant code if you put in the necessary effort, but it really requires an investment ... I'm still baffled that we have JS and then we put a typed language on top of it which is 5 times more complex than JS and takes at least 3 times longer to master, and all the while people are still disagreeing on its benefits.
IMO typescript once you know some of the pitfalls can become a super strong tool too determine bugs before you hit refresh without having too much overhead in typing. Its also great while refactoring since you see most of the bugs right away and don't need to search them.
Yes absolutely, it shines with refactoring and especially with autocomplete in an IDE like VSCode (you benefit from that even when you don't use TS but your libraries/imports do) ... and what I liked is that your code "documents itself" and that it makes you think a bit more thoroughly about code design.
I suppose that since that piece of code is within the scope of the setter it will assume that
.name
is the property, and not the setter itself?I edited the setter/getter example. It will work properly and be more clear.
I believe setters and getters are already available in plain javascript.
Hi,
Indeed Setters and Getters also exist in plain JS. Note that optional chaining has also been recently added to JS.
Thanks for the comment, I will edit my post to make this clear!
Hi Basile thanks for sharing.
Can you explain the firsr example a little more.
It is very interesting.
Best regards..
Hi Nader,
I created a new post to make the concept of User-Defined Type Guards (showed in the first example) easier to understand. Let me know if you have any questions.