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

Question: is there a more elegant way to representing type Line = string | Line[]? #3988

Closed
zpdDG4gta8XKpMCd opened this issue Jul 22, 2015 · 9 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@zpdDG4gta8XKpMCd
Copy link

I wish I could define a type as follows

type Line = string | Line[]; // <-- not a real TypeScript, do not attempt at home!

Looks like it's there is a fundamental limitation in the type system that doesn't allow doing so.

I ended up having my type defined like this:

export type Line = string|(string|(string|(string|(string|(string|(string|(string|(string|(string|(string|(string|string|(string|(string|(string|(string|(string|(string|(string|(string|(string|(string|(string|string|(string|(string|(string|(string|(string|(string|(string|(string|(string|(string|(string|string[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[])[];

but I don't like it because it only works that many times

Is there a more elegant and typesafe way of getting a type like this that works beyond 27 nested levels?

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Jul 22, 2015
@RyanCavanaugh
Copy link
Member

I don't think we have a way to represent an infinitely-expanding type alias like this.

@RyanCavanaugh
Copy link
Member

A shorter and sillier way of writing this type to depth 10

let x = ['', ['', ['', ['', ['', ['', ['', ['', ['', ['']]]]]]]]]];
type Line = string|typeof x;

@zpdDG4gta8XKpMCd
Copy link
Author

+1 i like it

@danquirk
Copy link
Member

I think #3496 covers your initial request.

@jeffreymorlan
Copy link
Contributor

type Line = string | LineArray;
interface LineArray extends Array<Line> {}

@RyanCavanaugh
Copy link
Member

@jeffreymorlan 🏆 👍!

@zpdDG4gta8XKpMCd
Copy link
Author

whose name shall it put on the check?

@mhegazy
Copy link
Contributor

mhegazy commented Aug 10, 2015

Looks like the original issue has been answered. please reactivate if you are running into other issues.

@davidcornu
Copy link

davidcornu commented Dec 15, 2017

There's an interesting limitation to the suggestion in #3988 (comment).

Given

type ItemOrArray<T> = T | ItemArray<T>;
interface ItemArray<T> extends Array<ItemOrArray<T>> { }

the following

const items: Array<ItemOrArray<number>> = [1, [2, [3, ["4"]]]];

will report an error

Type '(number | (number | (number | string[])[])[])[]' is not assignable to type 'ItemOrArray<number>[]'.
  Type 'number | (number | (number | string[])[])[]' is not assignable to type 'ItemOrArray<number>'.
    Type '(number | (number | string[])[])[]' is not assignable to type 'ItemOrArray<number>'.
      Type '(number | (number | string[])[])[]' is not assignable to type 'ItemArray<number>'.
        Types of property 'push' are incompatible.
          Type '(...items: (number | (number | string[])[])[]) => number' is not assignable to type '(...items: ItemOrArray<number>[]) => number'.
            Types of parameters 'items' and 'items' are incompatible.
              Type 'ItemOrArray<number>' is not assignable to type 'number | (number | string[])[]'.
                Type 'ItemArray<number>' is not assignable to type 'number | (number | string[])[]'.
                  Type 'ItemArray<number>' is not assignable to type '(number | string[])[]'.
                    Types of property 'push' are incompatible.
                      Type '(...items: ItemOrArray<number>[]) => number' is not assignable to type '(...items: (number | string[])[]) => number'.
                        Types of parameters 'items' and 'items' are incompatible.
                          Type 'number | string[]' is not assignable to type 'ItemOrArray<number>'.
                            Type 'string[]' is not assignable to type 'ItemOrArray<number>'.
                              Type 'string[]' is not assignable to type 'ItemArray<number>'.
                                Types of property 'push' are incompatible.
                                  Type '(...items: string[]) => number' is not assignable to type '(...items: ItemOrArray<number>[]) => number'.
                                    Types of parameters 'items' and 'items' are incompatible.
                                      Type 'ItemOrArray<number>' is not assignable to type 'string'.
                                        Type 'number' is not assignable to type 'string'.

but

const items: Array<ItemOrArray<number>> = [1, [2, [3, [4, ["5"]]]]];

will not.

Edit - this seems related to #13052.

@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
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

6 participants