Type checked dynamic calls in TypeScript

Benoit Lemoine
3 min readMar 23, 2017

All the code present in this article was tested with TypeScript 2.2.1 and Lodash 4.6.1

The emergence of static type checking in JavaScript has put an end to the dynamic programming approach. If you had the following snippet in your JavaScript

for it to work in TypeScript, the only solution is to cast unknownObject to any? Or is it? Spoiler: No, and this article will show you how to keep this kind of dynamic code without losing any type checking goodness.

Literal Types

A value can be of multiple types. For example:

In the last line of this example, "foo" is a literal type. It's a type that contains one and only one value and which share the same name as this value. The type "foo" contains the value "foo". Thus, this type is named a string literal type.

Using String Literal Types

String literal types are more precise than string - they can be seen as subtypes because they share the same structure. If we want to use one as a function parameter, we have to use generic programming and explicitly state this fact:

Retrieving a property dynamically

The type operator keyof allows you to retrieve the name of the attributes of an object. For example:

With this operator, it’s now possible to get a property dynamically while staying type safe.

Type guards

We can go further by using type guards. This feature lets you write a test (that will be executed at runtime) that will check whether a variable is effectively of a specified type. This way, you won’t have to cast this variable. An example could be:

But we can push our previous example a little further and create a generic function that will behave somewhat similarly to the has of lodash but will be statically checked as well.

Some shortcut syntax à la lodash

Lodash offers the possibility to use some of its function with a shortcut syntax like this:

Based on what we’ve just coded, we can improve and write our own type safe pluck:

We can do the same for the vast majority of callback shortcuts available in lodash, but this will be left as an exercise for the reader.

Conclusion

Now that we know how to implement some dynamic programming capability in TypeScript, should we use this? In my opinion, not everything should be used: has is very useful, in particular when working with some legacy code in JavaScript. pluck, on the other hand, adds a layer of complexity to the function signature for very little gain in usability (writing a string instead of a one line function). So I would advise not to use it. Anyway, as always in software programming, there is no absolute answer other than "use what make sense to you and your team".

Side Note on Dependent Types

You can see some kind of recurring pattern in the above examples: the return type of getProperty and pluck depends on the value of one of their parameters. So, can we say that TypeScript allows some kind of dependent typing? The straight answer is no. This confusion come from the fact that string literal types share the same name as their value. Do not be mistaken though, these functions truly depend on types and not on values.

--

--

Benoit Lemoine

I’m a full-stack developer, in love with functional programming and type systems. I’m working currently at Decathlon Canada, in Montreal QC.