Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

union with any shows as union in signature quickinfo but any in parameter quickinfo #58606

Open
sandersn opened this issue May 21, 2024 · 5 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@sandersn
Copy link
Member

sandersn commented May 21, 2024

Repro based on the one by @mackuba

// @filename: jsdocLowercaseObjectQuickInfo.js **
 * @param {object | null} o
 */
function create(o) {}

create/*1*/(undefined);

Compile with noImplicitAny: false and checkJs: true

Expected:
Quickinfo at /*1*/ is function create(o: any): void

Actual:
function create(o: object | null): void

Note:

  • Signature help is correct.
  • Parameter quickinfo is correct.
@sandersn sandersn added the Bug A bug in TypeScript label May 21, 2024
@sandersn sandersn added this to the Backlog milestone May 21, 2024
@fatcerberus
Copy link

Expected and Actual are swapped, I think?

@sandersn
Copy link
Member Author

No, it's the right way round. object becomes any when noImplicitAny: false, and signature quickinfo should reflect that.

@Andarist
Copy link
Contributor

So this runs into an existing weird situation with reusing existing type declaration. It's not even unique to JSDoc types.

type /*1*/O = {
    /*2*/foo: any | string
}

At marker 1 we can see:

type O = {
    foo: any | string;
}

but at marker 2 we can see:

(property) foo: any

Note that declaration emit preserves any | string here even in 5.4.

The reason why the type for @param gets printed as any is that it's the computed symbol's type that gets printed. When we hover over the function's symbol we end up serializing that symbol using serializeTypeForDeclaration (called by symbolToParameterDeclaration) and that prefers reusing the existing type node.

It's enough to wrap the type in this original repro into an object to get consistent non-reduced results:

/**
 * @param {{prop: object | null}} o
 */
function create2(o) {}

create2/*1*/(undefined);

With the above, { prop: object | null; } gets printed consistently. But that consistent result is misleading since the user won't easily notice that it's an any in disguise.

@sandersn sandersn changed the title JSDoc {object} shows as {object} in signature quickinfo but {any} in parameter quickinfo union with any shows as union in signature quickinfo but any in parameter quickinfo May 21, 2024
@fatcerberus
Copy link

@sandersn In that case, it’s not true that create(undefined) “should error”. That’s why I asked. 😉

@sandersn
Copy link
Member Author

The comment was left over from the original repro, because the original author wanted object | null to mean object, even with noImplicitAny: false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants