Typescript sealed union types — better factories without switch

Mike Vas
Nerd For Tech
Published in
3 min readFeb 17, 2022
Photo by Antonio Batinić from Pexels

If you’ve ever stumbled upon a weird world of programming then you’ve probably heard of Factory method pattern. It is really useful and can make your life easier ( don’t believe me, read what is it about and try to understand it’s pros and cons).

If you combine it with string literal type in typescript and javascript objects you will be able to create amazing things in no time.

Let’s see an example:

Even though this example has it’s shortcomings, it can show you how you can create discriminated unions utilazing the aformentioned concepts. We use _tag property to discriminate between different factories. It has type of union of string literal types and thus defined as finit set of possible string values. This way typescript compiler is aware of allowed values, and modern IDE’s ( or editors) can easily help you based on this.

After that we define IFactory interface that all factories must comply to. This way we can utilize full power of polimorphism and program towards interfaces instead of implementation.

Concrete factories ( Factory1, Factor2 and Factory3)are implemented in this manner just as example, implementation is totally up to business logic.

After that fun part comes. We are going to ditch switch statement in favour of javascript object ( or map in essence, if you want to use this strategy in different programming languages). So what is this object consisted of? If you’ve followed the article key’s are actually string literals from union used for _tag field, and values are functions that should return one of three factories from discriminated union. In order to achieve this type FactoryT has been defined as a function return type. Also, even though we could just create an object with previously mentioned keys and values, I’ve decided to go with a function, just in case you want to pass some options that are required for creation of object that will be returned.

In the end there is example of usage, it is artifical of course, that is why it states clientFactories[factoryType || "default"] because usually you probably won’t know if you have factory type and whether it is correct one, so the safest is to fallback to "default".

You can make this more complicated using generics, different parameter types, etc. Or make it simpler with just string literal types and type map. It is up to you :)

If you have any comments on how to improve this, please write them down. Also, if you like the article please clap and follow me.

Literature

  1. https://refactoring.guru/design-patterns/factory-method/typescript/example
  2. https://www.logicbig.com/tutorials/misc/typescript/discriminated-unions.html
  3. https://mariusschulz.com/blog/string-literal-types-in-typescript
  4. https://medium.com/codex/factory-pattern-type-script-implementation-with-type-map-ea422f38862

Support

Thinking about your next trip? Don’t let your credit card hold you back, start saving now and pay later with Cheapoair.com and Accrue Savings and save up to $150. Find out more!

--

--

Mike Vas
Nerd For Tech

Software Engineer interested in web and mobile development and ML. IG: https://www.instagram.com/mikevastech/ TW: @mikevastech, GitHub: mikevatech