Giter Club home page Giter Club logo

Comments (10)

MartinJohns avatar MartinJohns commented on April 30, 2024 1

Note that the type of prop is not actually changed. If you look at the type in the next line it's still correctly T extends "y" | "x".

So it's at most an issue with the type shown in the tooltip.

from typescript.

fatcerberus avatar fatcerberus commented on April 30, 2024 1

I would argue that, if this triggers no-unnecessary-type-assertion for prop as 'y' then that's correct - the assertion is indeed unnecessary if

const r1: 'y' = prop;

is already legal as Ryan suggests. prop will be treated as a 'y' in contexts where it matters so there's no reason to assert it to that type.

from typescript.

paradoxloop avatar paradoxloop commented on April 30, 2024

thanks @MartinJohns I have clarified the bug report title to make it clear that it is on the asserted line only.

Whether the issue is with the type shown in the tooltip or not is beyond my understanding of the typescript codebase. Downstream tools like eslint which rely on the typescript types report an error as if the type of prop is actually set to the incorrect value rather than just appearing incorrect in the tooltip.

from typescript.

jcalz avatar jcalz commented on April 30, 2024

Duplicate of #43873

from typescript.

RyanCavanaugh avatar RyanCavanaugh commented on April 30, 2024

We need to retain basically both the T and the "y" aspects of the type here, otherwise code like this fails:

function someFunction<T extends keyof typeof x>(prop:T): T {
  switch (prop) {
    case 'y':
      return prop;

Note that

const r1: 'y' = prop;

also doesn't error.

The "correct" type is both T and "y" depending on what you need to use it for. If the contextual target is a union we treat it as "y", otherwise it's T. So neither display is "wrong", but we can only show one at a time to the user obviously.

from typescript.

bradzacher avatar bradzacher commented on April 30, 2024

The issue is that from typescript-eslint's perspective for the rule no-unnecessary-type-assertion we inspect the left and right side of the assertion and compare the types to make a guess if they are the same type. If they're the same type then we error and flag the assertion as unnecessary.

The way we do this is in the most basic form - "are the type objects the same?" Not even doing any fancy type assignability checks - it all just boils down to if (left === right) report().

So in this particular case when we inspect the left we don't see the type T - we see the type "y". Obviously this is the exact same type as the right so we report.

There's no flags set on the left type either so we can't even guess that the left might be the generic type. The contextual type too is the same. Is there another API we can use to get the type of the left without the assertion here (eg see that it is the generic type)?

from typescript.

bradzacher avatar bradzacher commented on April 30, 2024

To clarify - it's not just what you show to the user - this is not a problem of intellisense has to display one so we pick the best one via some logic.

Instead it's what the type API itself reports for the expression. When there is no assertion it reports the type T. When there is an assertion it reports the type "y".

from typescript.

jcalz avatar jcalz commented on April 30, 2024

I suppose there'd be some issue if it became T & "y"?

function someFunction<T extends keyof typeof x>(prop: T) {
    if (prop === "y") {
        x[prop].toUpperCase(); // error
        const p: "y" = prop;
        x[p].toUpperCase(); // okay
        const q: T & "y" = prop; // error!
        x[q].toUpperCase(); // this would have been okay
    }
}

from typescript.

paradoxloop avatar paradoxloop commented on April 30, 2024

@jcalz my using of a switch in the example was probably a mistake. I don't think this is a duplicate of #43873 because the problem is not typescripts inability to narrow for extend but that it picks and choses in the same code block about whether it is narrowed (in a way that doesn't let us override without triggering reasonable eslint rules).

@RyanCavanaugh needing to keep the return type broad to enable returing T makes sense

IF statement example:
ES Lint Playground

Screenshot 2024-04-03 at 22 44 50

from typescript.

typescript-bot avatar typescript-bot commented on April 30, 2024

This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

from typescript.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.