The Widen <Type>

I love typescript, it makes my life super easy and makes my dev experience far superior. That said one gripe I’ve always had in complex typescript codebase is with nested types, especially using things like Pick or Omit you had to check the type defini…


This content originally appeared on DEV Community and was authored by Rahul Tarak

I love typescript, it makes my life super easy and makes my dev experience far superior. That said one gripe I've always had in complex typescript codebase is with nested types, especially using things like Pick or Omit you had to check the type definition, 4-5 levels deep to actually know what the type is, this can be quite annoying.

Recently I found a solution a great solution to this called Type Widening and it can be super easily implemented.

If you just want the basic type, here you go. That said I will break down how this works and how you can improve it below. You can also find a more advanced version of this with recursion and enum guards at bottom of the post.

export type ToPrimitive<T> = 
  : T extends string
  ? string
  : T extends number
  ? number
  : T extends boolean
  ? boolean
  : T extends (..._args: any[]) => any
  ? (..._args: Parameters<T>) => ReturnType<T>
  : T

/**
 * Expands a type so you can nicely seem the primitives
 */
export type Widen<T> = {
  [key in keyof T]: ToPrimitive<T[key]>
}

Usage

Usage is very simple just wrap the type you want with Widen<MyType> below is an embedded example which allows you to hover over the two types to see the difference

Extending the use of Widen

Enums

We use Enum quite a bit in our codebase and unfortunately there is no T extends enum in typescript, so to hack around it you much create a Blacklist type which you can skip over

// Unfortunately this is the only way I could find right now
type EnumBlackList = DogBread | CatBread | OtherEnums 

Recursion

We can modify ToPrimitive to make it recursive like this

type ToPrimitive<T> = T extends string
  ? string
  : T extends number
  ? number
  : T extends boolean
  ? boolean
  : T extends (..._args: any[]) => any
  ? (..._args: Parameters<T>) => ReturnType<T>:
    T extends object // Check if object and call itself
    ? { [key in keyof T]: ToPrimitive<T[key]> }
  : T;

You can play with a demo below, which has all three different iterations setup for you

How it works

Not going into too much detail here, just a brief summary

This uses a combination of unity types from Typescript with conditional types to enable this

T extends string checks if the type is based on type string, which can be used as a conditional check. This allows us to check our base primitives like string number and boolean

To add support for functions, we need to check if the type has the structure of a function which we are doing by checking T extends (...args: any[]) => any Then we are returning the function with its correct parameters and return type using the Parameter and ReturnType utility type

Final Type

type EnumBlacklist = // your enums go here like Enum1 | Enum2 | Enum 3

type Widen<T> = { [key in keyof T]: ToPrimitive<T[key]> };

type ToPrimitive<T> = 
    T extends EnumBlackList ? T :
    T extends string
  ? string
  : T extends number
  ? number
  : T extends boolean
  ? boolean
  : T extends (..._args: any[]) => any
  ? (..._args: Parameters<T>) => ReturnType<T>
    T extends object
    ? { [key in keyof T]: ToPrimitive<T[key]> }
  : T;

type Test = Widen<MyType>

Feel free to email me any questions or suggestion on how I can improve this type or post at rahul@modfy.video


This content originally appeared on DEV Community and was authored by Rahul Tarak


Print Share Comment Cite Upload Translate Updates
APA

Rahul Tarak | Sciencx (2021-08-18T00:00:07+00:00) The Widen <Type>. Retrieved from https://www.scien.cx/2021/08/18/the-widen-type/

MLA
" » The Widen <Type>." Rahul Tarak | Sciencx - Wednesday August 18, 2021, https://www.scien.cx/2021/08/18/the-widen-type/
HARVARD
Rahul Tarak | Sciencx Wednesday August 18, 2021 » The Widen <Type>., viewed ,<https://www.scien.cx/2021/08/18/the-widen-type/>
VANCOUVER
Rahul Tarak | Sciencx - » The Widen <Type>. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/08/18/the-widen-type/
CHICAGO
" » The Widen <Type>." Rahul Tarak | Sciencx - Accessed . https://www.scien.cx/2021/08/18/the-widen-type/
IEEE
" » The Widen <Type>." Rahul Tarak | Sciencx [Online]. Available: https://www.scien.cx/2021/08/18/the-widen-type/. [Accessed: ]
rf:citation
» The Widen <Type> | Rahul Tarak | Sciencx | https://www.scien.cx/2021/08/18/the-widen-type/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.