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

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

Closed
hinell opened this issue Feb 15, 2017 · 10 comments
Closed

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

hinell opened this issue Feb 15, 2017 · 10 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@hinell
Copy link

hinell commented Feb 15, 2017

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'.
@mhegazy
Copy link
Contributor

mhegazy commented Feb 15, 2017

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' }

@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Feb 15, 2017
@RyanCavanaugh
Copy link
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.

@hinell
Copy link
Author

hinell commented Feb 15, 2017

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.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 15, 2017

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.

@hinell
Copy link
Author

hinell commented Feb 15, 2017

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

No way!

@mhegazy
Copy link
Contributor

mhegazy commented Feb 15, 2017

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.

@hinell
Copy link
Author

hinell commented Feb 15, 2017

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.

@RyanCavanaugh
Copy link
Member

@hinell
Copy link
Author

hinell commented Feb 15, 2017

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.

@RyanCavanaugh
Copy link
Member

Good start - keep going 😉

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants