TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Object destructuring causes deprecated status to get lost

Open steved-stripe opened this issue 1 year ago • 2 comments

🔎 Search Terms

object destructing deprecated status lost @deprecated

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries

I don't think this is a regression, I haven't seen it work in the past.

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/FAFwngDgpgBAylEBXCAlKBnJAbEMC8MA3sDGTAPQBUVMAAgCZQQBOUAxgIYhQMxUVS5ALYB7JADsQALhgAKAJQEAfDABuogJYNgAX2DBqtRszZcefJBlgZRwxAAtNEgOYwo2a-0EAzSexBNUQkYa2QIRVkEcPQsXGIhMjZkFhCiMUkZeSV8VSJdfX1gdmCMPDY4vEIwlEUAbmAKnBAAOgypRUMKch6APRgmVg5uXhhODHcAD2gA3gBCAxKJMuIYdrxdAlDEWoUG9c6Kbv6GUUwJAHI8F0Q1zhYAa1HxgdNhiyA

💻 Code


type SetupResult = {
    /** @deprecated */
    mount: () => void
}

/** @deprecated use something else */
function setup(): SetupResult {
    return {mount: () => {}}
}

const result = setup();
result.mount()
//       ^ deprecated as expected!

const { mount } = setup();
mount()
// ^ doesn't get marked as deprecated

🙁 Actual behavior

The destructered mount property doesn't show up as deprecated when called.

🙂 Expected behavior

The destructered mount function should show up as deprecated when called.

Additional information about the issue

No response

steved-stripe avatar Jun 17 '24 16:06 steved-stripe

Wasn't there another issue like this where most of the JSDoc gets carried over but the @deprecated tag doesn't? I feel like I've seen this bug before.

fatcerberus avatar Jun 17 '24 17:06 fatcerberus

I think this is working as expected. In the playground, I see accessing the mount property to be deprecated.

image

I think instead you want the call to be regarded as deprecated:

interface DeprecatedMount {
    /** @deprecated */
    (): void
}

type SetupResult = {
    mount: DeprecatedMount
}

function setup(): SetupResult {
//...

Playground Link

It does seem like maybe there is an ergonomics issue here. It seems to ONLY work with interface declarations, not with function type expressions nor with call signatures. In both cases the @deprecated directive is silently ignored:

type SetupResult1 = {
    mount: /** @deprecated */ () => void
}
type SetupResult2 = {
    mount: { /** @deprecated */ (): void}
}

rotu avatar Aug 27 '24 19:08 rotu