microsoft/TypeScript

Include Default Parameter Values in Signature Help

mjbvz opened this issue ยท 43 comments

mjbvz commented

From microsoft/vscode#28925

TypeScript Version: 2.4.0

Feature Request
signatureHelp current shows when a parameter is optional but does not include any information about that parameter's default value:

function foo(x = 10) { }
foo(|)

Result of TSServer signatureHelp on foo

[Trace  - 5:42:22 PM] Response received: signatureHelp (378). Request took 20 ms. Success: true 
Result: {
    "items": [
        {
            "isVariadic": false,
            "prefixDisplayParts": [
                {
                    "text": "foo",
                    "kind": "functionName"
                },
                {
                    "text": "(",
                    "kind": "punctuation"
                }
            ],
            "suffixDisplayParts": [
                {
                    "text": ")",
                    "kind": "punctuation"
                },
                {
                    "text": ":",
                    "kind": "punctuation"
                },
                {
                    "text": " ",
                    "kind": "space"
                },
                {
                    "text": "void",
                    "kind": "keyword"
                }
            ],
            "separatorDisplayParts": [
                {
                    "text": ",",
                    "kind": "punctuation"
                },
                {
                    "text": " ",
                    "kind": "space"
                }
            ],
            "parameters": [
                {
                    "name": "x",
                    "documentation": [],
                    "displayParts": [
                        {
                            "text": "x",
                            "kind": "parameterName"
                        },
                        {
                            "text": "?",
                            "kind": "punctuation"
                        },
                        {
                            "text": ":",
                            "kind": "punctuation"
                        },
                        {
                            "text": " ",
                            "kind": "space"
                        },
                        {
                            "text": "number",
                            "kind": "keyword"
                        }
                    ],
                    "isOptional": true
                }
            ],
            "documentation": [],
            "tags": []
        }
    ],
    "applicableSpan": {
        "start": {
            "line": 3,
            "offset": 5
        },
        "end": {
            "line": 3,
            "offset": 5
        }
    },
    "selectedItemIndex": 0,
    "argumentIndex": 0,
    "argumentCount": 0
}

When the default value is a simple literal type, it would be helpful to display this default value in the signature help. This information could be included in the displayParts response

๐Ÿ‘

See feedback request here for also showing this information via the JsDoc comments: https://developercommunity.visualstudio.com/content/problem/230423/jsdoc.html

Any Update on this?

Updates?

ivoiv commented

Also interested in updates.

Hi #27442 was closed but how do I show default value ? I tried ctrl+shift+space on optional parameter but it did bot show the default value at all.

@qiulang it's not implemented. that bug was closed because it's a duplicate of this one, but this one is still open and unaddressed.

This would be great. It's something you kind of just expect to be there, and could cause someone not familiar to assume that the default is undefined, which may be confusing in certain contexts.

Also applicable to JS, not just TS

Any Updates on this?

Make sure you give a ๐Ÿ‘ reaction to the issue - I feel that would help it get recognized more than simply bumping with comments

this is really frustrating as the work around are all pretty hacky and make the jsdocs less helpful in other ways :(

Would like to have this for jsdocs also

for JSDoc JavaScript IntelliSense too

any update on this?

Not sure if there has been any activity on this but I am also quite interested in this. I've been forced to add the default as a part of my description for each variable.

See feedback request here for also showing this information via the JsDoc comments: https://developercommunity.visualstudio.com/content/problem/230423/jsdoc.html

This was marked as low priority. Why is this the case?

@mjbvz What is the expected response from TSServer in this case?

  "parameters": [
    {
      "name": "x",
      "documentation": [],
      "displayParts": [
        {
          "text": "x",
          "kind": "parameterName"
        },
        {
          "text": "?",
          "kind": "punctuation"
        },
        {
          "text": ":",
          "kind": "punctuation"
        },
        {
          "text": " ",
          "kind": "space"
        },
        {
          "text": "number",
          "kind": "keyword"
        }
        ???
      ],
      "isOptional": true
    }
  ]
mjbvz commented

@a-tarasyuk I think something like:

     ....,
     {
          "text": " ",
          "kind": "space"
        },
        {
          "text": "=",
          "kind": "punctuation"
        },
       {
          "text": " ",
          "kind": "space"
        },
        {
          "text": "123",
          "kind": "stringLiteral"
        },

But double check with someone on the TS team for that

@mjbvz Thanks. @DanielRosenwasser Could you validate the response example?

That looks correct to me (though to be pedantic, 123 wouldn't be a stringLiteral without quote marks around it).

What exactly do we want to do when the expression is huge though? Especially when both the type and the expression are big?

Any updates?

@DanielRosenwasser Do you mean something like this?

function fn(a = {
  b: () => {},
  c: 2,
  d: {
    e: [1, 3, 4]
  }
}) {}

Not sure what response should be in the above case. Maybe we only need to allow this for primitives or return the entire definition, I'm just not sure what kind should be in this case.

@mjbvz What do you think about a more complex case?

image

No default value support.

image

@RyanCavanaugh @mjbvz this was created in 2017, how much longer must it remain in "Awaiting More Feedback" limbo? This is important information to provide users without (or no access to) external documentation.

I understand the desire to make this feature 'smart', but I think over-engineering is delaying this from getting done. In the JSDoc spec, it suggests a few examples and all you have to do is show what is literally defined in the optional parameter as text, not interpret arguments as given by the function.

Or if it is desired to show default values based on the function itself, and not JSDoc comment, this should be split into two issues instead of merging all the JSDoc related issues into this issue.

In my mind it'd display the default values based on the function itself, which can be replaced if there's a superseding JSDoc comment.

Bump. This issue has been around for a long time.

Not sure if this had been addressed previously, but I've found a workaround using type parameters with JSDoc using the @template tag which is arguably more powerful than simply just default parameters.
More details can be found via the JSDoc reference on the TypeScript documentation

Fix for @tjx666's snippet:

/**
 * ๅฏนๆ•ฐๅญ—ๅ–ๆŒ‡ๅฎšไฝๆ•ฐ็š„ๅฐๆ•ฐ
 * @template {number} [X=3]
 * @param {number} num
 * @param {X=} fractionDigits
 */
function toFixed(num, fractionDigits) {
    var numStr = num.toString(10);
    var dotIndex = numStr.indexOf('.');
    if (dotIndex === -1) return num;

    if (fractionDigits === undefined) fractionDigits = 3
    var multiplex = Math.pow(10, fractionDigits);
    return Math.round(num * multiplex) / multiplex;
}

Fix for the original example:

/**
 * @template {number} [T=10]
 * @param {T} x
 */
function foo(x = 10) { }

There does appear to be some discrepancy between the JSDoc implementation and the TypeScript interpreter, as the fix is roughly equivalent to the invalid code:

function foo<T extends number = 10>(x: T = 10) { }
// Type 'number' is not assignable to type 'T'.
//  'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'number'.ts(2322)
i7eo commented

same issue๐Ÿ˜ข

This is a incorrect type: type F1 = (a: number = 7) => void.
But F2 is correct: type F2 = (a?: number) => void;.
However F2 can be implements with a default parameter value such as

type F2 = (a?: number) => void;
const func2: F2 = (x: number = 7) => { };

If we try to get the type of (x: number = 7) => { }, that is (a?: number) => void:

const func3 = (x: number = 7) => { };
type F3 = typeof func3;  // (a?: number) => void

Because default parameter value is not a legal type rule.

How about make it legal?
Maybe the rule can be more detailed. for example:

type F1 = (a: number = 7) => void; // , declare default parameter with the special value.
const f11: F1 = (a: number = 7) => { } ;    // โœ“, matchs exactly
const f12: F1 = (a?: number) => { };     // โœ—  , expect default parameter value
const f13: F1 = (a?: number = 6) => { };  // โœ— , expect the special default parameter value (7)

type F2 = (a?: number) => void;
const f21: F2 = f11;   // โœ“, f21() can run expectedly

Thus, if we use F1, we know it's default parameter value is always 7.

Would love to get any progress or updates on this

Would love this!

Bump

Another vote for this to be implemented ASAP!

I hope I can see this implemented before I retire. If not I may not be able to die in peace.

I was looking for a solution or workaround for this and when I tried to react to a comment I realized that I've already done it... Two years ago ๐Ÿ˜ฉ

How is this not already a thing? Updates please.

I also want this. For JavaScript docs

Today I have to put this information in the parameter description

Using pure JavaScript:

/**
 * Sum 2 numbers
 * @param {Number} a First number
 * @param {Number} [b=0] Second number, defaults to 0.
 * @returns The sum
 */
function foo(a, b){
    if (b === undefined) b = 0;
    return a + b
}

image

need for javascript as well (not only ts).

It's been 7 years at this point since the original request for a default values to appear in IDE popups. Every time I've brought this up in VSC they said it's a TypeScript repo issue - which feels ridiculous so many years later. I hope someone like @sandersn can raise this internally so it could be re-prioritized, as many programmers do not review the code of the function they are using, just the popup documentation, which can lead to unusual consequences if they are not made aware of default values.

microsoft/vscode#177529
#27442
microsoft/vscode#59609

This is the only thing holding me our team our company the world back from subscribing to copilot! Don't delay, elevate its priority today!

Hello, 2025 is here and this issue still isn't resolved.