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

feat(60442): show deprecation warnings on implementations of a deprecated property #60454

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

a-tarasyuk
Copy link
Contributor

Fixes #60442

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Nov 7, 2024
@a-tarasyuk a-tarasyuk marked this pull request as ready for review November 8, 2024 15:28
@spaque99
Copy link

Any update on merging this change?

@jakebailey
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 17, 2025

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 17, 2025

Hey @jakebailey, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/164551/artifacts?artifactName=tgz&fileId=A1C0C719604D3B99B71BF02D9310ED868E53723F4E9CD8C7A078388A6E31827E02&fileName=/typescript-5.8.0-insiders.20250117.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/[email protected]".;

const symbol = getSymbolOfDeclaration(declaration);
if (
isDeprecatedSymbol(symbol) && symbol.declarations &&
isTypeAssignableTo(type, getTypeOfSymbol(symbol))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to check assignability? Isn't the name sufficient?

I think that this code leads to this incorrectly flagging a deprecation:

type I = {
    /**
     * @deprecated
     */
    text: string;
} | {
    text: string | number;
};

function f(i: I) { return i; }
f({ text: 'a' });

const a: I = { text: 'a' }
a.text;

Nightly shows what I think is "correct", which is that it's not deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakebailey thanks for the additional case. I'll check it.

Why does this need to check assignability?

Since the prop has the same name but different types, I thought comparing the prop types was necessary here — am I wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose there is, but I would think the logic would proceed similarly to other places that do deprecation; I believe there's another place that issues deprecations on contextual types which looked different (but I'm replying on my phone so can't find it easily 😅)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function I'm thinking of is createJsxAttributesTypeFromAttributesProperty, but it doesn't check assignability at all!

Copy link
Contributor Author

@a-tarasyuk a-tarasyuk Jan 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, it doesn't, and doesn't support this case 😅. Anyway, I’ll explore a better solution...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that correct behavior? (Or at least, the behavior I said was better?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to check assignability? Isn't the name sufficient?

interface A {
    a: number;
}
interface B {
    /** @deprecated */
    a: string;
}
const a: A | B  = { a: 'a' } // has to be deprecated
const b: A | B  = { a: 1 }

At this case, the contextual type is a union type (A | B), and the initializer type is string. The getPropertyOfType returns a single symbol with combined declarations for each PropSignature. To properly handle deprecated declarations, need to identify the type used in the initializer and compare it with one of the union types. If we could resolve the appropriate type at this stage (e.g., B for 'a' and A for 'b'), it would eliminate the need for assignability/relation checks. If you have any thoughts or suggestions, I’d be grateful to hear them. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show deprecation warnings on implementations of a deprecated property
4 participants