Posted on

Exposing the type of a typescript class while hiding the implementation

When we define a typescript class, we are actually defining two things, a constructor function, and a type. The instances constructed using the constructor defined by a class will have the type of the class.

One might wonder, if it is possible, say from a library, to expose only the type of the class and not the actual type constructor. The goal here may be to prevent direct instantiation of the class, or prevent consumers from monkeying around with the prototype chain of the constructor.

Of course, direct instantiation can be prevented using private constructors, but that is only if the consumers are using typescript. A consumer using plain javascript, or who is liberal with use of any is more than welcome to instatiate the class directly.

One obvious approach is that we could define an interface, make our class implement the interface and expose just the interface.

This works, but requires quite a bit of extra effort and duplication of signatures (assuming that interface is being created just for this purpose only).

But, what if we could just strip out the run time entity (constructor function) of a class definition, and just retain the type of the class. This is indeed possible and very easy to do.

We can just make an interface which extends a class (and doesn’t add anything extra).

Exporting this interface provides our typescript consumers access to the type of the class, but doesn’t provide anyone access to the constructor function or the prototype chain.

If we are not ever exposing any instance of this class, and the class is for internal use only, we are pretty much done here.

However, in case we are exposing instances of this class, then we are not finished, because, any instance of the class also facilitates access to the constructor through the constructor property (which can be overriden) and the prototype chain can be accessed through Object.getPrototypeOf or the controversial (and legacy __proto__ property.

The safest way to completely hide the implementation of prototype chain while exposing the instances is to wrap the instances in a Proxy that delegates method access and property access to the underlying target instance.

Posted on

Simplifying generics-heavy typescript code using Container Interfaces, Extractor Types and Companion Namespaces

Writing generics-heavy code code in Typescript can sometimes be arduous, especially because typescript doesn’t facilitate higher kinded types at language level.

So, a function that accepts multiple arguments of generic types often has to accept type parameters of all these generic types in order to retain type safety:

This can get cumbersome fast, especially when the parameterized types have constraints on the type parameters because now these constraints also have to be replicated:

Continue reading Simplifying generics-heavy typescript code using Container Interfaces, Extractor Types and Companion Namespaces

Posted on

ReasonML vs TypeScript – First impressions

This post summarizes preliminary observations while comparing ReasonML and TypeScript during selection of a reasonably (pun-intended) type safe language for frontend development. The observations here are somewhat biased in favor of experienced javascript developers and focusses primarily on frontend development workflow and does not take into account the (primary) native backend of Reason.

While this post primarily compares Reason and TypeScript, much of what is outlined about TypeScript equally applies to flow as well.

Continue reading ReasonML vs TypeScript – First impressions

Posted on

Typescript and validations at runtime boundaries

Typescript team has explicitly stated that they don’t intend to extend typescript’s static type checking to the runtime.

Typescript Design Goals lists the following in the section on Non-goals:

Add or rely on run-time type information in programs, or emit different code based on the results of the type system. Instead, encourage programming patterns that do not require run-time metadata.

While on one hand this design goal is advantageous in that the output generated by typescript is very close to what hand written javascript would have looked like. And the runtime cost of typescript remains close to zero, therefore adoption of typescript does not alter performance characteristics of an application.

However, this also implies that for cases when static typing cannot help us we need to separately write validators using a validation library (eg. Joi) which has to be kept in sync with the typescript types.

This post outlines an approach to eliminate this redundancy using the io-ts library by Giulio Canti. This approach has also been adopted by some other libraries like MobX State Tree and Runtypes.

Continue reading Typescript and validations at runtime boundaries

Posted on

Using helm to select tide completion candidates

Tide (TypeScript Interactive Development Environment for Emacs) uses a custom hydra-derived popup menu for prompting the user to select candidates when there are many completion options available.

However, this is jarring when the rest of your emacs environment is configured to use helm as the completion engine.

Fortunately, this is easy to fix by overriding the tide-popup-select-item implementation to use a custom helm source derived from the completion list.

Continue reading Using helm to select tide completion candidates