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

consider syntax for tuple literals: (['a', 2]) // [string, number] #9217

Description

Problem

There is no way to get a tuple value without explicit type annotation:

var tuple = ['hey', 1]; // (string|number)[]

Solution

Add new syntax for tuple literals:

var tuple = (['hey', 1]); // [string, number]

related #9216

Activity

  1. blendsdk commented on Jun 16, 2016

    @blendsdk

    would this help?

    
    type tuple = [boolean, number, string];
    
    var t2: tuple = [1, 2, 2]; // error
    var t3: tuple = [true, 1, "abc"];  // ok
    
  2. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    this is stated as a problem that is sought to be solved

    There is no way to get a tuple value without explicit type annotation:

    meaning that you example only works thank to explicit type declaration which i wish could be avoided

    type tuple = [boolean, number, string];
    
  3. blendsdk commented on Jun 16, 2016

    @blendsdk

    Ah..... I misread the question. I am inclined to say type tuple = Array<any> but then it is not a tuple anymore.

  4. mhegazy commented on Jun 16, 2016

    @mhegazy
    Contributor

    we have talked about this before, we could not come up with a proposal that works and looks right.. some of the options considered

    • special syntax, var x = [| 1, 2 |]
    • special function, var y = tuple(1,2)
    • a type annotation, var z: [...] = [1,2]

    nothing seemed palatable to be frank.

  5. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    why would not this work: (['hey', 1])?

    • works fine with the existing syntax
    • highly unlikely to be a breaking change
    • doesn't affect JavaScript semantics at all (can be executed as written and will work as expected)
    • resembles a object-literal-literal x => ({value: x})
  6. mhegazy commented on Jun 16, 2016

    @mhegazy
    Contributor

    this is rather subtle. looking at it i would not guess, and if i did it by mistake i would not be able to see why it is working any differently.
    For a while contextual type did not go through parenthesized expressions, and ppl tripped over it consistently.

  7. ahejlsberg commented on Jun 16, 2016

    @ahejlsberg
    Member

    We did at one point consider the ([x, y]) syntax for tuples, but as Mohamed Hegazy (@mhegazy) says, we thought it too subtle. Someone looking at ([x, y]) would have absolutely no intuition that it produces a different type than [x, y].

  8. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    my few centes, speaking for myself:

    • right now seeing something like ([]) rather than [] looks strange to me, so it's a red flag anyway
    • this pattern is unlikely to be used intentionally, yet it's very likely to be by mistake
    • if so, why won't we take advantage of something being no use
    • it's ok for new features to call for new capabilities, this is how it usually goes
  9. dsbl41 commented on Jun 16, 2016

    @dsbl41

    FWIW I kind of like Aleksey-Bykov proposal.
    I would have the intuition that ([x, y]) is different from [x, y] as it looks similar to an arrow function with a concise body returning an object literal:

    var f = x => {}; // returns void
    var f = x => ({}); // returns {}

    With the proposed ([x, y]) syntax:

    var f = x => ['hey', 1]; // returns (string|number)[] type
    var f = x => (['hey', 1]); // returns [string, number] type

  10. ntrrgc commented on Jun 16, 2016

    @ntrrgc
    Contributor

    In my projects I use something like this:

    export function tuple<T1>(value: [T1]): [T1]
    export function tuple<T1,T2>(value: [T1, T2]): [T1, T2]
    export function tuple<T1,T2,T3>(value: [T1, T2, T3]): [T1, T2, T3]
    // ...
    export function tuple(value: any[]): any[] {
        return value;
    }
    

    The usage is very simple and explicit:

    var myTuple = tuple(['hey', 1]); // [string, number]
    
  11. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    Alicia Boya García (@ntrrgc) this is my current workaround: #9216 (comment)

  12. aluanhaddad commented on Jun 16, 2016

    @aluanhaddad
    Contributor

    I don't like the analogy with the arrow function returning object literal syntax because that syntax itself is kind of a hack to get around an issue with how arrow functions are specified in ECMAScript.

    That said, it's a useful hack but it has no impact on the type of the object literal, it has an impact on the type and value of the function, and no one writes them in parentheses except to return them from expression bodied arrow functions.

  13. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    like it or not:

    • it already happend and can't be fixed
    • it does what it does, and people get used to it
    • it's better than nothing

    so it's easier to get along with it than deny

  14. mhegazy commented on Jun 16, 2016

    @mhegazy
    Contributor

    i disagree with the "better than nothing". i still find this fairly confusing, let a side undiscovered.

  15. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    Mohamed Hegazy (@mhegazy) i was talking about x => ({ value: x }) syntax that is used for returting object-literals in lambdas that Aluan Haddad (@aluanhaddad) happened not to like

    of which, better than nothing means there is no better syntax for object literal results in lambdas (aside from the statements), and this is something no one can change anymore, despite being ugly, it works for a lot of people

    we've seen it, we hated it but we ate it, and it worked out

    so there is a precedent

  16. ahejlsberg commented on Jun 16, 2016

    @ahejlsberg
    Member

    Aleksey-Bykov I think where the analogy breaks down is that { value: x } and ({ value: x }) have the same type, whereas [x, y] and ([x, y]) would have different types with what you're proposing.

  17. zpdDG4gta8XKpMCd commented on Jun 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    Anders Hejlsberg (@ahejlsberg), I admit, the syntax is not ideal, and what you said is definitely a weak point of the idea, at the same time it has a number of strong points, as far as i can tell, that were also mentioned

    to my defence: the fact that ([]) and [] currently mean the same is a waste of valuable syntax, because you don't usually see ([]) in the wild, all I am saying is that it might get a better use

  18. aluanhaddad commented on Jun 17, 2016

    @aluanhaddad
    Contributor

    Aleksey-Bykov I was objecting to the analogy for the exact reasons that Anders Hejlsberg (@ahejlsberg) mentioned. I was not objecting to the work around syntax for returning object literals from expression bodied arrow functions.

    I think it's a shame that expression bodied arrow functions require a kludge to work with object literals but the syntax could be worse.

    I'm saying the analogy is flawed.

  19. aluanhaddad commented on Jun 17, 2016

    @aluanhaddad
    Contributor

    After re-reading my comment I realize I could have been clearer. I was indeed saying that it's not great to follow the precedent of a syntax that is a hack in the first place.
    I was also trying to get across that the use of parentheses is completely different in that context because it alters the function returning the value, not the value itself.

  20. Artazor commented on Jun 23, 2016

    @Artazor
    Contributor

    I know about "not playing at the expression level syntax" rule...
    but just as a fantasy:

    x = <>[ 1, 'a', true ]  // or [ 1, 'a', true ] as <> - type strongifier
    x = #[ 1, 'a', true ] // - AFAIK # now is invalid symbol. treat #[ - as a single delimiter
    x = [: 1, 'a', true :] // symmetric smiley brackets
  21. zpdDG4gta8XKpMCd commented on Aug 7, 2016

    @zpdDG4gta8XKpMCd
    Author

    Closing in favor of #10195

  22. 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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions