Reputation: 1694
I am using VS Code
and it helps a lot when working with Typescript
as it tells you when current issues there are without needing to transpile.
I am using Typescript
with nodeJS
and it works really well.
The only issue I have is so called "null / undefined checking functions".
See this example:
class User {
public someProperty: string | undefined;
// ...
public get canDoSomething() {
return this.someProperty != undefined;
}
}
let myUser: User = ...
This works nicely:
if (myUser.someProperty != undefined) {
// at this point myUser.someProperty is type string only (as it cannot be undefined anymore
}
However this fails
if (myUser.canDoSomething) {
// because typescript still thinks that myUser.someProperty is string | undefined and not just string, even though this method checks for that.
}
Any idea how I would tell typescript? Because sometimes a method like that is cleaner than keep comparing the properties to undefined itself.
Thanks
Upvotes: 4
Views: 1335
Reputation: 249706
Type narrowing works with specific syntactic constructs. if (obj.prop != undefined)
is one such construct, that will inform the compiler prop
can't be undefined.
In your case you perform the check in a property. Typescript will not follow the implementation of the getter to see that it performs the null check.
You could use a custom type guard (a method/function with special syntax that informs the compiler of type side effects) :
class User {
public someProperty: string | undefined;
public canDoSomething() : this is this & { someProperty: string} {
return this.someProperty != undefined;
}
}
let myUser: User = new User
if (myUser.canDoSomething()) {
myUser.someProperty.big()
}
I would recommend with sticking with the simpler if (myUser.someProperty != undefined)
though unless you have a good reason to encapsulate the check.
Edit
this is this & { someProperty: string}
informs the compiler that the type of the object this method was invoked on (this
) has now changed (is
) to a new type (the intersection this & { someProperty: string}
).
this
in the intersection this & { someProperty: string}
acts as the type for the current class (called polymorphic this
) and will be either User
or any class that derives from user (could have used User
instead of this
but it would not have worked on derived classes.
The intersection (&
) with { someProperty: string}
will mean that the type after the check is both whatever class we had before (this
) and an object with a property someProperty
of type string
. Since User
already had someProperty
the type of someProperty
in this intersection will work out to User['someProperty'] & string = (string | undefined) & string = string
efectively removing undefined
from the type of someProperty
in the resulting type.
Upvotes: 6
Reputation: 372
You might want to changed:
myUser.someProperty != undefined
To
typeof myUser.someProperty !== "undefined"
This will check the typing instead of the value.
Upvotes: -1