You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
src/index.tsx(3,3): error TS2345: Argument of type'string' is not assignable to parameter of type'"a" | "b"'.
This is just a toy example, and can be fixed with enums or other approaches.
I'm actually having this issue, where tsc gives me a lot of error in the CSS.
For example
src/index.tsx(33,13): error TS2322: Type '{ flex: number; justifyContent: string; alignItems: string; backgroundColor: string; }' is not assignable to type'ViewStyle'.
Types of property 'alignItems' are incompatible.
Type 'string' is not assignable to type'"flex-start" | "flex-end" | "center" | "stretch"'.
Please also note that
t("a");
doesn't give any error, but I can't really use it to solve the react issue.
I'm not sure if there is another issue related to the same problem. I tried to search in the opened issues but I haven't found anything.
You need a type annotation to give b a literal type:
constt=(a: "a"|"b")=>a;constb: "a"="a";t(b);
I think it is reasonable to require a type annotation to get a literal type for a var or let since you might later mutate the variable, but it does seem a bit silly not to just infer the literal type for a const.
Not sure if this can help, but this is a snippet of the original error
import*asReactfrom'react';const{ Component }=React;import{AppRegistry,StyleSheet,Text,View}from'react-native';conststyles={container: {flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',},welcome: {fontSize: 20,textAlign: 'center',margin: 10,},instructions: {textAlign: 'center',color: '#333333',marginBottom: 5,},};classTestextendsComponent<any,any>{render(){return(<Viewstyle={styles.container}><Textstyle={styles.welcome}>
Welcome to React Native!
</Text><Textstyle={styles.instructions}>
To get started, edit index.ios.js
</Text><Textstyle={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text></View>);}}exportdefaultTest;
I receive errors when I assign the various styles. Basically every css property that is described as union generates an error like the one in the open post
The only reason I didn't do this is because it's a breaking change. Either way, someone is going to have to write a type annotation. Given the types of programming const is used for, the ergonomics might win out here, but we should discuss it.
Once you add this type annotation everything works because we have a contextual type for each of the properties. (Plus of course you get completion lists when writing the object literal and errors if you write the wrong values.)
Even with the proposed change to consider the initializer for a const a literal type location, we couldn't trasitively to the same for properties in an object initializer because there is no indication that they are const. Specifically, you might want to assign a new value to styles.container.alignItems, but you wouldn't be able to if we inferred type "center" for it.
Thanks Daniel Rosenwasser (@DanielRosenwasser), wasn't the original rules set out to widen when used to assignment to let/var as per your #6167 (comment)? I understand this one is tricky though and I'm still reading through all comments....
The thing is that much of the time you'd end up needing to annotate types anyway. For instance, a string literal in a property declaration would be widened to string:
interfaceSubscribe{actionType: "Subscribe";email: string}// ...typeAction=Subscribe|ChangeEmail|UnsubscribedeclarefunctionprocessAction(a: Action): void;constx={actionType: "Subscribe",email: "hello@emailplace.com",}// Oops! x has type '{ actionType: string; email: string }'processAction(x);
So it was arguable how much better it was, because that is clearly one of the cases we really cared about anyway.
It was also incredibly complex, subtle, and sort of ad hoc. Imagine trying to explain the rule set to users of why their literal types disappeared in this one place but not another.
But, in your example above, the const only applies to x and not actionType. So I would argue that the compiler is right to error against this, actionType can be changed to anything. Some control flow analysis may enable some narrowing on this, but I would be happy to force a cast, changing "Subscribe" to "Subscribe" as "Subscribe".
Realize this problem is multi-faceted, but I think making it more consistent makes it simpler to explain. From your gist, problem 1 seems to be solved by the widen on mutable binding rule, and problem 2 seems to be solved by the use the most wide comparison type rule.
Activity
ahejlsberg commentedon Jul 2, 2016
You need a type annotation to give
ba literal type:I think it is reasonable to require a type annotation to get a literal type for a
varorletsince you might later mutate the variable, but it does seem a bit silly not to just infer the literal type for aconst.Daniel Rosenwasser (@DanielRosenwasser) Mohamed Hegazy (@mhegazy) Ryan Cavanaugh (@RyanCavanaugh) I recall discussing this before, perhaps we should consider making this change.
ahejlsberg commentedon Jul 3, 2016
Specifically, I think we should add this to #9407 by considering the initializer of a
constvariable declaration a literal type location.bolismauro commentedon Jul 3, 2016
Not sure if this can help, but this is a snippet of the original error
I receive errors when I assign the various styles. Basically every css property that is described as union generates an error like the one in the open post
DanielRosenwasser commentedon Jul 3, 2016
The only reason I didn't do this is because it's a breaking change. Either way, someone is going to have to write a type annotation. Given the types of programming
constis used for, the ergonomics might win out here, but we should discuss it.ahejlsberg commentedon Jul 3, 2016
Mauro Bolis (@bolismauro) I'm not sure you'll be able to avoid a type annotation. It works if you do the following:
Once you add this type annotation everything works because we have a contextual type for each of the properties. (Plus of course you get completion lists when writing the object literal and errors if you write the wrong values.)
Even with the proposed change to consider the initializer for a
consta literal type location, we couldn't trasitively to the same for properties in an object initializer because there is no indication that they areconst. Specifically, you might want to assign a new value tostyles.container.alignItems, but you wouldn't be able to if we inferred type"center"for it.ahejlsberg commentedon Jul 3, 2016
Mauro Bolis (@bolismauro) Alternatively you could use the
astype assertion operator:bolismauro commentedon Jul 4, 2016
Anders Hejlsberg (@ahejlsberg) your explanation makes absolutely sense.
I'll use the
asoperator to fix the problem, thanks!DanielRosenwasser commentedon Aug 5, 2016
Should we close this?
joewood commentedon Aug 29, 2016
Anders Hejlsberg (@ahejlsberg) your comment #9489 (comment) - was this ever discussed in more detail? Is there a reason why const types aren't narrowed to their literal type?
DanielRosenwasser commentedon Aug 29, 2016
Joe Wood (@joewood) mainly because it breaks this
But it's sort of been on the table ever since we first discussed it.
joewood commentedon Aug 29, 2016
Thanks Daniel Rosenwasser (@DanielRosenwasser), wasn't the original rules set out to widen when used to assignment to let/var as per your #6167 (comment)? I understand this one is tricky though and I'm still reading through all comments....
DanielRosenwasser commentedon Aug 29, 2016
The thing is that much of the time you'd end up needing to annotate types anyway. For instance, a string literal in a property declaration would be widened to string:
So it was arguable how much better it was, because that is clearly one of the cases we really cared about anyway.
It was also incredibly complex, subtle, and sort of ad hoc. Imagine trying to explain the rule set to users of why their literal types disappeared in this one place but not another.
I also dug up some notes on a gist from way back about this: https://gist.github.com/DanielRosenwasser/57f111bcb5f52457cc6d
joewood commentedon Aug 29, 2016
But, in your example above, the const only applies to
xand notactionType. So I would argue that the compiler is right to error against this,actionTypecan be changed to anything. Some control flow analysis may enable some narrowing on this, but I would be happy to force a cast, changing"Subscribe"to"Subscribe" as "Subscribe".Realize this problem is multi-faceted, but I think making it more consistent makes it simpler to explain. From your gist, problem 1 seems to be solved by the widen on mutable binding rule, and problem 2 seems to be solved by the use the most wide comparison type rule.
ahejlsberg commentedon Sep 2, 2016
Possible fix for this issue in #10676.
mhegazy commentedon Sep 20, 2016
Original issue should be addressed by #10676