1

Assume I have an interface

interface Types{
  name?:string,
  age?:number
}

When I call the below function why does Intellisense not show the options of interface Types that I can pass?

function display(options: Types) {
    console.log(options.name);
}

display({name: "hey"})

Is there a way Typescript shows the values that I can pass to the function? Example:

function display(options: { name?: string, age?: number}) {
}

when I call the above function, it shows me that I can pass an object with name and age to it. Is there a way to achieve the same with using interface as the argument type as shown above?

shank087
  • 492
  • 8
  • 17
  • Maybe you should tag this with your specific IDE. If I try [on the TypeScript playground](https://tsplay.dev/WzGV4w) and use the IntelliSense features there, including autocompletion prompting, I get what looks like the information you're saying is missing (see [this image](https://i.imgur.com/Xxed9rW.png) too). Are you doing something or seeing something different? – jcalz Mar 01 '23 at 15:29
  • @jcalz - Thanks, seeing the options after re-starting VS Code. Also, is there a way Typescript shows the values that I can pass to the function? Example: function display(options: { name?: string, age?: number}) {}, when I call this function, it shows me that I can pass an object with name and age to it. Is there a way to achieve the same with using interface as the argument type as shown above? – shank087 Mar 01 '23 at 16:24
  • Maybe like [this](https://tsplay.dev/N557MN)? But that seems to be outside of the scope of the question as asked; if you want to ask that could you [edit] the question post so it explicitly asks that? Or should we close the question as irreproducible (because it seemed to do with some temporary issue with VS Code)? – jcalz Mar 01 '23 at 16:29
  • @jcalz Thanks for your answer. Exactly I am looking for. Edited the question. Pls post it as the answer. Will accept it. – shank087 Mar 01 '23 at 16:34
  • 1
    Okay I'll do so when I get a chance. – jcalz Mar 01 '23 at 16:35

1 Answers1

1

TypeScript uses various heuristics to determine how to display a given type; often interfaces 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

jcalz
  • 264,269
  • 27
  • 359
  • 360