TypeScript uses various heuristics to determine how to display a given type; often interface
s are displayed as-is by name and not expanded out to properties. IntelliSense-enabled IDEs should give developers the option to go to the definition of a given symbol, so those who see an interface
name like Types
and don't know what it is should be able to find out themselves.
But it is possible to represent a type in a form that TypeScript will tend to evaluate further, as discussed in How can I see the full expanded contract of a Typescript type?, so as to display its properties inline. For example, a conditional mapped type:
type Expand<T> = T extends infer O ? {[K in keyof O]: O[K]} : never;
For types T
that are plain object types without call or construct signatures, Expand<T>
is essentially an identity function; we take the type parameter T
and copy it into the type parameter O
, and then perform an identity mapping over O
. So we're not really changing the call signature of display()
when we write this:
function display(options: Expand<Types>) {
console.log(options.name);
}
But now when you write display
followed by an open parenthesis, you should be prompted with the following IntelliSense hint:
display(
// display(options: { name?: string | undefined; age?: number | undefined; }): void
Which is what you want. Of course this isn't magic, and if you hover over the definition of display
itself, you will get the definition as-written, which is potentially more confusing than the original version:
// function display(options: Expand<Types>): void
So it's up to you what you want to do.
Playground link to code