microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.02k stars 12.49k forks source link

Binding element incorrectly reported as having `any` type in JS with JSDoc starting with 5.6.2 #59936

Closed burtek closed 1 month ago

burtek commented 2 months ago

πŸ”Ž Search Terms

Binding element implicitly has an any type 7031

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?strictNullChecks=true&target=9&suppressImplicitAnyIndexErrors=true&ts=5.6.2&filetype=js#code/PQKhCgAIUgBAHAhgJ0QW0gbwPICMBWApgMYAuAvpANrED2AdgGYCWA5gLpQwIrpYAKKUs0QAbADwAlErWQATcQHJ8AZwaLIAH0jK19Yhu26GAVkUAaSCtLJm9VlXYA+J5RoMWrAHSI5c5sIMYgBizKKEKpzQwOCEAB7wsqSQjACu+oH0kPDIhEi5AMIebAAUmFCQlb7+mSFhEQBcWBWVrZCqDJAAvNRRrZQ9mOTgA1jkAJTNbXT0auFeorSsJR304yNAA

πŸ’» Code

/**
 * @param {Object} [config]
 * @param {Partial<Record<'json' | 'jsonc' | 'json5', string[]>>} [config.additionalFiles]
 */
export function prepareConfig({
    additionalFiles: {
        json = []
    } = {}
} = {}) {
    console.log(json)
}

πŸ™ Actual behavior

json is errored as Binding element 'json' implicitly has an 'any[]' type.(7031) even though it's typed as string[]

image

πŸ™‚ Expected behavior

No error expected, as json is typed as string[]

Additional information about the issue

This worked well in 5.5.4 but broke with upgrade to 5.6.2. It works correctly in .ts file, but breaks in .js file with JSDoc.

Andarist commented 2 months ago

I'll fix this as part of https://github.com/microsoft/TypeScript/pull/59924

burtek commented 2 months ago

@Andarist ok, thanks. I guess it's gonna go out as 5.6 patch bump?

Andarist commented 1 month ago

@burtek in the end I decided to create a separate PR for this one since I was able to fix this independently and the other PR raises some design questions. The fix is available here: https://github.com/microsoft/TypeScript/pull/59975

As to your question, this is a recent regression so I'd advocate to bacport a fix to 5.6 but that's up to the TS team.

ahejlsberg commented 1 month ago

This issue actually existed before 5.6, but only for array binding patterns (playground link):

/**
 * @param {[[string[]?]?]} [x]
 */
function f1([[json = []] = []] = []) { return json } // Implicit any[] error on json binding element

In 5.6 we aligned array and object literal padding and the issue then showed up in object binding patterns as well:

/**
 * @param {{ a?: { json?: string[] }}} [x]
 */
function f2({ a: { json = [] } = {} } = {}) { return json } // Implicit any[] error on json binding element

The culprit here is logic we have in widenTypeInferredFromInitializer to issue no-implicit-any errors in JS files. We shouldn't be issuing these errors when we're obtaining the implied type for a binding pattern. I'll put up a PR to fix. Unfortunately the fix in #59975 isn't the right one.