Conditionally Protect Properties in Typescript
03 December 2024
Updated: 03 December 2024
Type Guards
So, type guards are really handy in Typescript as they let us check if something meets a certain requirement before moving along, for example, given the following user type:
We can define a type guard that checks if the user is fully is active
before allowing certain things. To do this we usually use a type guard, that looks like this:
The important thing in a type guard is that it takes something of one type and asserts something about that type, e.g. that it is an ActiveUser
in the above. This is done by returning a boolean, if it is true
then the assertion applies, otherwise it does not
And normally, we would use it like so:
Gaurded Class
The above solution is usually good enough. But it’s also possible to couple the types of these checks while not providing direct access to the underlying object. This is useful in cases where we may want to restrict access to some functionality unless a certain set of checks pass
To do this, we can encapsulate the value and check into a class, e.g. the Guarded
class below:
In the above, we define a Guarded
class htat has a type of a Safe
and Unsafe
value. These generics can be inferred by the arguments provided to constructor
Next, we define the isSafe
method on the class that is a gaurd that says something about this
which is the instance itself.
So, we can use Guarded
to wrap something that we want to only make available under certain scenarios:
What’s great is that this safe
check is re-run whenever we want to access the value
, this means that we can make certain properties available based on some other state that can be checked in the safe
method
Furthermore, the Typescript compiler itself will prevent you from accessing value
if we determine it is unsafe. This protects us both at a runtime as well as compile time
Note
The first idea of Type Guards is quite often used and should be good enough for normal use
Withr egards to the Guarded
idea, use with caution. The idea here it to create a certain safety for consumers of some code, but this is at the expense of complexity and should be used with care. Outside of the “can it be done” discussion I haven’t really had much use for something like this since usually a normal type guard is good enough