Forcing IntelliSense to resolve a type definition
I’m using intersection types very often to build up new types from other types by extending them. Here’s an example:
|
|
However, even with this simple example, the IntelliSense tooltip shows just the literal type definition without explicitly resolving the intersection type:
This is not very helpful when encountering this type somewhere and we just want to know which properties are contained, especially for more complex or even mapped types.
Here is a type alias that forces IntelliSense / TypeScript to expand a type.
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
When we use it in the declaration of the NumericDropdownItem
type from above,
|
|
the IntelliSense tooltip becomes much more helpful:
The Expand
type uses conditional type inference to make a copy of type T
into a new type variable O
and then a mapped type which acts essentially as identity type that iterates through the copied type’s properties.
The conditional type inference is used to distribute union types and to force the compiler to evaluate the true
branch of the conditional. Without it, sometimes the compiler will just output the mapped type { [K in keyof SomeTypeName]: SomeTypeName[K] }
, which is not what we want to see.
The Expand
type defined above only works on top-level properties. In case we want to expand the proprety types as well, we can easily define a recursive variant. The T extends object
conditional is added to not unneccessarily drill down into primitive types.
|
|
This helper type can improve the developer experience, but should only be used where individual property names need to be looked up very often. Conceptually, it is a no-op, but repeated use can add up computationally and increase the compile time quite a lot, especially the recursive variant.
The article’s code can be found in this TypeScript Playground.