镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[Literals][Indexes][Type assertion] Is that a bug? #14093

Description

@hinell

Literal types related topics & conversations

Related to this issue PR that regulates literal type inference and its behavior in self-type changing can be found here: #10676

TypeScript Version: 2.1.6

Code

interface T {[key: string]: 'literal'}
let  FOO: (obj: T) => T;
let DOOMED = { prop:'literal' } // DOOMED.prop === 'string' but not the literal

FOO(DOOMED)         // fails as expected
FOO(<T>DOOMED)      // fails
FOO(DOOMED as T)    // fails!

let SAVED: T = { prop:'literal' }
FOO(SAVED) // ok

Expected behavior:
Type assertion is expected to work in both cases <> and as but doesn't

Actual behavior:
Fails

Error:

FOO(<T>DOOMED)      // fails
       ~~~~~~~~~

error TS2352: Type '{ prop: string; }' cannot be converted to type 'T'.
  Property 'prop' is incompatible with index signature.
    Type 'string' is not comparable to type '"literal"'.


FOO(DOOMED as T)    // fails!
       ~~~~~~~~~~~

error TS2352: Type '{ prop: string; }' cannot be converted to type 'T'.

Activity

  1. mhegazy commented on Feb 15, 2017

    @mhegazy
    Contributor

    as T and <T> are identical in effect. They are just two syntacytic forms for the same operation, type assertion.

    Type assertion checks for a valid conversion from one type of the other, this can be in both directions, i.e. up/down cast. In this example, neither types is assignable to the other, so {prop: string} is not assignable to T, since prop is not "literal", nor is T assignable to {prop: string} since T does not have the required property called prop, all it has is a constraint, that properties will be of type "literal".

    The real issue is that a string literal type in a mutable location (i.e. let, property declaration or array literal member) are not reflected in the type unless stated at declaration time. So DOOMED needs to have a type let DOOMED: T or the property needs to have a type assertion: { prop:'literal' as 'literal' }

  2. RyanCavanaugh commented on Feb 15, 2017

    @RyanCavanaugh
    Member

    Also, DOOMED has the type { prop: string }; this is a type that we don't know isn't aliased by some value that has properties which are not of type string.

  3. hinell commented on Feb 15, 2017

    @hinell
    Author

    or the property needs to have a type assertion: { prop:'literal' as 'literal' }

    Well I already know that but what if I want to assert like a boss (as or <>) keeping my code simple and clean from extra let DOOMED declarations or assertion of thousands of existing 'literal's in objects? 😎
    There has to be the way any way.

    Type assertion checks for a valid conversion from one type of the other,

    Why? Aren't they expected to convert a variable type into provided one?
    Sounds like a mess.

  4. mhegazy commented on Feb 15, 2017

    @mhegazy
    Contributor

    Why? Aren't they expected to convert a variable type into provided one?
    Sounds like a mess.

    if all what you want is to make the assignment work, assert to any.

  5. hinell commented on Feb 15, 2017

    @hinell
    Author

    if all what you want is to make the assignment work, assert to any.

    No way!

  6. mhegazy commented on Feb 15, 2017

    @mhegazy
    Contributor

    No way!

    ?
    you do not want the compiler to check that one is assignable to the other, nor do you want to shut it up using any.

  7. hinell commented on Feb 15, 2017

    @hinell
    Author

    Explicit variable type declaration works well but what this issue is up to is that type assertion actually doesn't works as expected. That's why it can't be shut up just by any-ing eveyything. If I use any, then it senseless to use types.

  8. hinell commented on Feb 15, 2017

    @hinell
    Author

    Well thanks. let's read the first line:

    TypeScript allows you to override its inferred and analyzed view of types any way you want to.

  9. RyanCavanaugh commented on Feb 15, 2017

    @RyanCavanaugh
    Member

    Good start - keep going 😉

  10. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions