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

Alternative syntax for type assertions to allow XML-like syntax extensions #296

Description

The current syntax for type assertions prevented the React team from adding TypeScript support to JSX. While E4X was a failure, XML-like syntax extensions is a good idea, which might make it into some next ECMAScript version. If it happens, it will be impossible to incorporate that syntax into TypeScript because of type assertions.

(ported from http://typescript.codeplex.com/workitem/2608)

Activity

  1. CyrusNajmabadi commented on Jul 29, 2014

    @CyrusNajmabadi
    Contributor

    "it will be impossible to incorporate that syntax into TypeScript because of type assertions."

    This is not the case. As i mentioned in the original thread:

    Hey Guys,

    TS developer here (and guy who wrote the current 1.0 parser). I haven't read through the entire thread. However, from looking at a few examples of what you're asking for, this seems like it would be very easy to add in a fork of the typescript parser, if one were so willing.

    The algorithm would be pretty darn simple. First, you'd prescan the file, looking for XML close tag candidates. i.e. you'd have a regexp that would match strings like (allowing for spaces between things). With that, you'd have a table mapping potential end tags to locations in the file.

    You'd then need to augment the scanner and parser. The parser would be updated such that if it hit a potential opentag, it would need to speculatively parse ahead to see if this was actually XML or just a cast. The end-tag table would be helpful here as it would allow you to even decide if it was worthwhile to do that speculative parse. i.e. if you saw and had never seen in your doc, then there would be no point speculatively parsing. On the other hand, if you had and did have a tag later on, then it would be worth going forward.

    If you never find the end tag, then you rewind parsing, and go ahead parsing the entity as a type assertion expression.

    This approach is very similar to the one we already need to take today to deal with the ambiguity between type assertion expressions and generic arrow function expressions. Speculative lookahead is necessary (and already done here), so it's no stretch to augment it to support XML. The only little trick here is to get the end tags to ensure you don't speculatively parse every time, most of the time when it's not going to be fruitful.

  2. danquirk commented on Jul 29, 2014

    @danquirk
    Member

    Cyrus covered some of the issues here. Changing the syntax for type assertions would be a pretty serious breaking change. If we have to do so for some reason in the future (like a future EcmaScript version) then I think we cross that bridge when we get there.

  3. thorn0 commented on Aug 8, 2014

    @thorn0
    Author

    I didn't propose to change the syntax. I asked for adding an alternative one. It's not a breaking change.

  4. CyrusNajmabadi commented on Nov 12, 2014

    @CyrusNajmabadi
    Contributor

    Georgii Dolzhykov (@thorn0) I think the subtle issue here is that while you are proposing an alternative syntax for type-assertions, you seem to be implicitly stating that the existing type-assertion syntax would then be used for the xml-like syntax extensions. That part is what could be a significant breaking change.

    That said, i still think this is very possible to do. However, i don't think it currently has enough interest to warrant the work right now. If you can show that ther'es enough interest in the community for this, that could change. Thanks!

  5. koistya commented on Jan 3, 2015

    @koistya
    If you can show that ther'es enough interest in the community for this, that could change.
    — CyrusNajmabadi

    There is about 100k monthly downloads of Rect.js library from the npm registry. Even if only 10% of this audience would willing to use TypeScript with React+JSX that looks big enough, IMHO. But, as of now, all this audience is steadily switching from TypeScript to Flow.

  6. DanielRosenwasser commented on Jan 3, 2015

    @DanielRosenwasser
    Member

    For the record, you can easily subsume this functionality with template strings/tagged template strings, which will be available in 1.4.

  7. borekb commented on Mar 19, 2015

    @borekb

    Now that TypeScript is a first-class citizen in Angular (2.0), it would be nice if React got some love too. There are ways to integrate them today but they are clunky, not very IDE-friendly, etc. I'd personally love if I could combine the two technologies seamlessly.

  8. Lenne231 commented on Mar 20, 2015

    @Lenne231

    👍 definetly a must have! I would love to have type safety in my whole application, even in the views

  9. thorn0 commented on Mar 20, 2015

    @thorn0
    Author

    Cyrus Najmabadi (@CyrusNajmabadi)

    I think the subtle issue here is that while you are proposing an alternative syntax for type-assertions, you seem to be implicitly stating that the existing type-assertion syntax would then be used for the xml-like syntax extensions. That part is what could be a significant breaking change

    It's not the case. Right, the existing syntax wouldn't be used in the files containing JSX expressions. However, the new syntax is all that is needed from TypeScript here. It's not a breaking change at all. The JSX expressions would be processed by the JSX processor, not by TypeScript. The TS compiler would get normal TypeScript code as its input, without any extensions. How is this a breaking change?

    The React team would've been glad to add the support for the TS constructions to JSX, but the current syntax for type assumptions just makes it too complicated.

  10. borekb commented on Mar 20, 2015

    @borekb

    This is a noob question but how comes that Flow doesn't have problem with angle brackets + generics + JSX and TypeScript does?

  11. thorn0 commented on Mar 20, 2015

    @thorn0
    Author

    There is no problems with generics, only with type assertions. Flow doesn't use angle brackets for them.

  12. 108 remaining items

  13. RyanCavanaugh commented on May 19, 2015

    @RyanCavanaugh
    Member

    Removing a commonly-used top-level production from a programming language essentially never happens, and for good reason. Syntactic breaking changes, especially ones that aren't absolutely necessary, are a good way to make sure no one uses your language.

    We don't expect a large majority of people to be using TSX. Telling everyone else they have to change syntax for the sake of a feature they don't even use is rude at best.

  14. AlicanC commented on May 20, 2015

    @AlicanC

    I don't think anyone would care since Microsoft customers are aIready used to spam that "Next" button to convert every VS solution they get their hands on.

    You know that JavaScript suffers from past bad decisions like the "==" operator and the optional semicolons. An advantage of TS is that it is always compiled into something that every browser can run. With a proper "What's Changed?" blog post and a TS1-to-TS2 converter, a change like this would be no problem.

    So I completely disagree that syntactic changes needs to be absolutely necessary. You could change the syntax every week and I wouldn't care as long as it was done for a good reason.

    But, you believe that JSX will not be used by majority so not wanting to do a change like this is also completely understandable.

    Let's hope I will be the only one who got upset to see JSX being treated like a second-class citizen.

  15. CyrusNajmabadi commented on May 20, 2015

    @CyrusNajmabadi
    Contributor

    JC (@AlicanC)

    I don't think anyone would care since Microsoft customers are aIready used to spam that "Next" button to convert every VS solution they get their hands on.

    TypeScript is used by people who don't use VS.

    An advantage of TS is that it is always compiled into something that every browser can run. With a proper "What's Changed?" blog post and a TS1-to-TS2 converter, a change like this would be no problem.

    This now means that people can't share code with other people who use different verisons of the compiler than them. It means people learning can't use code samples written for a previous version of the compiler. etc. etc.

    Let's hope I will be the only one who got upset to see JSX being treated like a second-class citizen.

    How is JSX being treated like a second class citizen?

  16. AlicanC commented on May 20, 2015

    @AlicanC

    Cyrus Najmabadi (@CyrusNajmabadi)

    This now means that people can't share code with other people who use different verisons of the compiler than them. It means people learning can't use code samples written for a previous version of the compiler. etc. etc.

    Why do you think that would be the case? We can even share code between Coffee and JavaScript thanks to conversion services. The choice between TS1 and TS2 isn't even like the choice between Coffee and JS. If you are using TS1, just run the converter and start using TS2.

    And about learning material, they get outdated even when you don't introduce breaking changes to your language. Does my 10 year old JavaScript book has working examples in it? Yes. Should I care about Netscape support like it tells me to or take anything else serious in that book? No. It is actually worse because the examples work. Nothing warns you about using a bad practice, nothing tells you that you are doing something stupid. You can just keep learning from it and become the most useless developer in the universe.

    And then you start telling people to use linters or you start projects like W3Fools to keep people away from bad practices. You can't break JavaScript or HTML because you will be breaking millions of websites. You can break TS or Coffee because the developer can just run a converter and keep rocking on.

    (Again, I'm not saying these to support my proposal of changing the <T>v syntax. Though I could say these for the ES6-incompatible module/import syntax if you are going to decide on keeping it.)

    How is JSX being treated like a second class citizen?

    It doesn't look like you are eager to do this right. It looks like you want to implement it one way or another and just get over it. There is a project which introduces XML support to JSX. A lot more people could benefit from an implementation that not only supports React-like applications, but also XML.

    The support could also be under .ts instead of .tsx with further discussion in #3022. For example, Ryan Cavanaugh (@RyanCavanaugh) closed that issue by giving the {{ "hello world \}\} \{\{" }} example. I don't think he has no idea about Heredoc/Nowdoc or CDATA which are used to tackle problems like that. When you see people start pointing out false dead ends while they could easily further the discussion, you start to think that they just don't want to do it. If I read something like "How do we solve that problem then?" instead of "This is a dead end!", I would at least think that there were interest in what people think.

  17. thorn0 commented on May 20, 2015

    @thorn0
    Author

    JC (@AlicanC) Luckily, the React team tries to keep JSX abstracted away from React. The JSX spec even contains parts that aren't used by React (namely, XML-like namespaces). From what I can see, the TypeScript team adheres to the same principle and tries to come up with a generic support for abstract JSX, not for JSX+React only.

  18. CyrusNajmabadi commented on May 20, 2015

    @CyrusNajmabadi
    Contributor

    Why do you think that would be the case?

    Because certain syntax constructs are no longer supported in both compilers. So a person cannot compile the same file in one compiler that they compile in the other.

    No. It is actually worse because the examples work. Nothing warns you about using a bad practice, nothing tells you that you are doing something stupid. You can just keep learning from it and become the most useless developer in the universe.

    None of the documentation about how to do type assertions is teaching you a bad practice.

    It doesn't look like you are eager to do this right.

    To me, Ryan laid out a very strong case for why the current approach is a good way to do things. For example providing a solution that is more compatible rather then less compatible can definitely be argued to be a better way to handle things depending on what you think is important.

    It would probably also be good for the discussion to try to avoid overly loaded words like "right". We must all recognize that many people evaluate change with different weights to the pros/cons than us, and even altogether different criteria than us. There is rarely a case where something is truly 'right'. Rather, it's the best solution that's available given all the different things we need to balance. Please keep that in mind as we discuss this.

  19. AlicanC commented on May 20, 2015

    @AlicanC

    Georgii Dolzhykov (@thorn0) The Careless documentation states:

    Careless is a fork of Facebook's JSX, that allows custom tags, custom attributes and XML namespaces : the only (?) XML features missing from Careless are doctypes and XML comments.

    If that statement is wrong, please correct us. If that is right, then TSX could be a JSX superset instead of a direct JSX implementation so XML dudes can benefit more from it.

    Cyrus Najmabadi (@CyrusNajmabadi)

    Because certain syntax constructs are no longer supported in both compilers. So a person cannot compile the same file in one compiler that they compile in the other.

    So are you going to have:

    • Two ways to do type assertions,
    • Two ways of importing files and
    • Three extensions (.tsx and .ts being 99% the same)

    in your language to fight that? Isn't that a lot of pollution and possible confusion? I would rather break the language than have that much pollution.

    None of the documentation about how to do type assertions is teaching you a bad practice.

    As soon as you introduce the .tsx extension and v as T, people who want to do type assertion in .tsx will end up in this SO and get the wrong answer:
    http://stackoverflow.com/questions/19461479/what-is-the-type-assertion-operator-for-in-typescript

    So some of your learning material is already set to be wrong and suggesting (and using) <T>v will also be wrong since it won't work in .tsx files. <T>v will never be the answer for "How to do type assertion in TypeScript?" anymore because it will only be able to do type assertion in half of TypeScript.

    Also, when support for ES6 Modules become stable, the answer for "How to import files in TypeScript?" will be "Use ES6 syntax." because teaching people a more universal solution will be better than teaching them a TS-specific solution.

    Even without any breaking changes, you are already breaking your documentation and other learning material. People who are going to use <T>v type-asserted code sample in a .tsx file are already fucked.

    "Oh crap, we don't have support for that." moments should not end up being resolved by adding another way to do the same thing. Either break <T>v (since learning material will go bad no matter what) or implement JSX in a way that is compatible with <T>v.

  20. danquirk commented on May 20, 2015

    @danquirk
    Member

    Isn't that a lot of pollution and possible confusion? I would rather break the language than have that much pollution.

    Can you name some other successful languages that are designed like this? How many different ways does C# have to define anonymous functions due to its evolution over time? What's the correct way to use pointers in C++ now (*, smart, shared, etc)? There're a great many books, tutorials and SO answers that are now out of date. You are vastly underestimating the pain of breaking changes to most people, especially when weighed against convenience related changes that don't fix correctness issues or feature gaps. The history of programming languages bears this out pretty clearly (look at the schism caused by Python 3 and how it affected adoption).

  21. CyrusNajmabadi commented on May 20, 2015

    @CyrusNajmabadi
    Contributor

    So are you going to have:
    Two ways to do type assertions

    Yes. That gives people the compatibility they expect from a programming language, and enables us to sidestep a difficult ambiguity between JSX and TS. It's a win-win for me.

    I would rather break the language than have that much pollution.

    That's fine. But recognize that your priorities do not necessarily reflect everyone else's. There have been many times i've wanted to 'break' a language i'm using (including languages i've worked on). Depending on how good the change is, and how bad the break is, the breaks have been taken. But many many times, the break simply isn't worth it.

    In this case, as with all others, an evaluation will be made as to whether or not a break is appropriate. However, my strong feeling is that this will not meet the bar. For me, the negative impact far outweighs the positives that have been listed. However, the team will consider it and feed in all our priorities to try to make the best decision possible in a scenario where there are no perfect answers.

  22. thorn0 commented on May 20, 2015

    @thorn0
    Author

    JC (@AlicanC) "a fork of Facebook's JSX" sounds like "a fork of HTML". It's not clear what they're trying to say there. Did they fork React's JSX transformer? Or did they 'fork' the JSX spec to change it somehow, which means they don't adhere to the original spec any more? In the latter case, they shouldn't expect much compatibility from other projects.

    JSX is a "syntax extension to ECMAScript without any defined semantics". The JSX constructions are just a new building block for JS expressions. TypeScript needs to know their syntax to parse them, to type-check their elements (see below), and to output these syntax constructions as-is without transforming them into JS. The transformation should be done by some other transpiler - be it React's transformer, or Careless, or something else.

    The tricky type-checking part is discussed in #3203. Unfortunately, the solution proposed there doesn't look React-agnostic at all.

  23. LeDominik commented on May 24, 2015

    @LeDominik

    Just my highly subjective 2¢: For me <T> for a type assertion just feels (and felt) wrong. Most type operations have operator-style with typeof for type guards and instanceof for the classic OO thing. Using as or a more specific astype seems more logical to me.

    IMHO type assertion are one of the weirder constructs anyways because you still have to check with instanceof, which lots of people just forget. Autocomplete / IntelliSense will just give you the "correct" type once you decorated with <T> and most will stop thinking about it exactly there. It's just an assertion (erased in transpilation as per standard) without an assertprefix anywhere which is well known since C-macros to have no effect in production code. A really safe variation IMHO would be something like this:

    if(let x = someFunc("circle") instanceof Circle) {
     ...
    }

    The <T> notation in my mind is generics, generics and of course XML, so in my mind it's like a opening gate for some kind of variation. And while a type assertion is of course connected to all this (types!) it's more an operation.

    But as said: Just a user's opinion; probably the suggested construct collides with lot's of other cases :bowtie:. However (again as a user) the way React naturally uses HTML (which is just not going to go away as much as many dislike the XML-syntax) feels much more natural than any Angular 1.x felt or Angular 2 looks like... and Typescript is a language for the web that should not go down the road of complexity and confusion that most other languages went so early in life. I always found the "strict"; mode-switch inspiring, using it cleanly with versions would allow to upgrade step-by-step and assisted by tools. Old versions would just not support XML-constructs.

  24. thorn0 commented on Jun 29, 2015

    @thorn0
    Author

    As #3564 is merged into master, this issue can be closed.

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

Metadata

Metadata

Labels

CommittedThe team has roadmapped this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions