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
import{MyNamespace}from'my-package';// importing Class objects:const{ NavLink, NavGroup }=MyNamespace;// VALID// if we want the types as well:type{NavLink,NavGroup}=MyNamespace;// NOT VALID// So we have to go manual: typeNavLink=MyNamespace.NavLink;// VALIDtypeNavGroup=MyNamespace.NavLink;// VALID
Expected behavior:
Being able to use destructuring for types same as we use for objects.
Actual behavior:
Can only use destructuring for objects.
If this is supported, it seems like it should work for the import statement as well so that one may acquire both the type and value space meanings if desired.
import{NavLink,NavGroup}=MyNamespace;// NOT VALID
Reacted by Shlomi Assaf, Basarat Ali Syed, Cole Chamberlain, Tom, Louis-Dominique Dubeau, Cliff Meyers, KyleDavidE, bySabi Files, fbontin, Eric Swann and 15 more
Aliasing is problematic when the type to be imported has generics:
// ./lib.tsexporttypeFoo<Textendsstring>={foo: T}// ./index.ts// ERRORtypeFoo=import('./lib').Foo;// We have to repeat generics:typeFoo<Textendsstring>=import('./lib').Foo<T>;// Separately: expected error, but got none. Bug?typeFoo<T>=import('./lib').Foo<T>;
Would love a way to get around this; one practical example where I'm experiencing this is when using the output from protobuf.js's pbjs and pbts tools. They use namespaces, and you can end up with a huge list of imports at the top of the file that could be a lot more compact.
Ran into this today. I'm writing a tool that exports tables/types from PostgreSQL to TypeScript definitions and I'm forced to generate namespaces (in order to avoid name collisions across schemas).
I feel that namespaces are not first class citizens because of this limitation making them too unwieldy.
I'd love to be able to do:
/// this:import{app_public}from"./types";import{user,user_info}=app_public;/// or even better, this:import{app_public: {user,user_info}}=from"./types";
This would make it so much easier to get types from namespaces, especially in instances where you are exporting a class and destructing it only grabs the value. (Ran into this today)
Andrew Powell (@shellscape) pretty much everything TypeScript could possibly ever do was suggested at one point within the first two years of its release, which was about 10 years ago. Needless to say, in that timeframe, we have not done every possible thing, nor could/should we have. C++ is nearing 40 years old at this point and is still adding new features. You'll need to readjust expectations around how fast a language can responsibly add features, unfortunately.
Reacted by Tylor Reynolds, Tim Perry, Elliot Wright, Shinigami, I Putu Yoga Permana, Eliaz Bobadilla, Cody Swartz and Sokcuri
Reacted by Robert DeLuca and Jeremy Walker
Reacted by Shinigami, Dan Falk, Eliaz Bobadilla, Cody Swartz and Sokcuri
Ryan Cavanaugh (@RyanCavanaugh) I think you're conflating expectations of execution with expectations of comment. it is not unreasonable to suggest that an issue 5 years old should get at least one comment from a maintainer.
I can't figure out if it's unfortunate or hilarious that the only comment this issue received from a maintainer, especially the Development lead for the TypeScript team at Microsoft. was to scold a user who pointed out the lapse of activity by the maintainers of the project on the issue. Whether or not you feel my cheeky reply was in poor taste, that's a bad look.
Reacted by Robert DeLuca, Cody Swartz, Sokcuri and Jeremy Walker
That's valid, and I'm not trying to scold you. We have thousands of open suggestions and if we were going around keeping every suggestion "fresh", we'd do nothing else.
Anyway, concerns I see here:
Every feature starts at minus 100 and this syntax doesn't enable you to do anything you couldn't do before; it's purely sugar (sweet as that might be)
There might be better use of this syntactic space in the future; "using" it to do destructuring seems like the most logical thing but why close it off now?
Very strong problems when we think about how namespacing / member access works here.
To expand on the latter, a few different examples were cited in-thread
// Set 1type[NameType,ValueType]=Parameters<typeofmethodWithNameAndValue>;typeFoo={x: number;y: number;}type{X,Y}=Foo;// Set 2type{FooType,BarType}=import('./types');
Notably, Set 1 and Set 2 propose different behaviors for how this should work. In Set 1, the requested operation is T["n"] (property lookup), in Set 2, the requested operation is T.n (namespace access). We can't pick and choose here because for T and n, there might be meanings for both.
Reacted by Andrew Powell, Cody Swartz, Clint Nelson and Yona Appletree
OT: Apologies that I came off that way! "This has been open X years" is a frequent form of unproductive complaining and it sets me on edge whenever I see it, but your request was valid. I can do better and will try to.
Reacted by Abdullah A. Hassan, Robert DeLuca, Cody Swartz, Sokcuri and Peter Gomez
Reacted by Robert DeLuca, Cody Swartz, realfresh, Sokcuri, Peter Gomez, Clint Nelson, Yona Appletree and Dane David
Andrew Powell (@shellscape) pretty much everything TypeScript could possibly ever do was suggested at one point within the first two years of its release, which was about 10 years ago. Needless to say, in that timeframe, we have not done every possible thing, nor could/should we have. C++ is nearing 40 years old at this point and is still adding new features. You'll need to readjust expectations around how fast a language can responsibly add features, unfortunately.
Hey, just wanted to say we appreciate all the hard work you guys are doing! There's no place for negativity in open source development. Nobody has the right to throw around blame. That's a dangerous mindset and anyone wanting a feature bad enough to complain about it can add it themselves and make a PR. (or even make their own fork if there's a disagreement)
Notably, Set 1 and Set 2 propose different behaviors for how this should work. In Set 1, the requested operation is T["n"] (property lookup), in Set 2, the requested operation is T.n (namespace access). We can't pick and choose here because for T and n, there might be meanings for both.
I propose a disambiguation syntax for this:
// Set 2type{namespaceFoo: { X, Y }, BarType }=import('./types');
Here we're explicitly stating that we want to destructure the members of Foo as a namespace and not as a type. TypeScript can expect Foo to be a namespace and throw an error if it isn't.
re: Set 1 - I believe it is not needed whatsoever since what it's really doing is treating a type as a namespace. Destructuring types is a mistake - the only reason one should use the property access operator is for complex generic types, and well... you can't use that syntax in generic types.
re: "it's purely sugar" - sure. but it's extremely useful sugar that removes a ton of visual clutter.
edit: elaborating on "types shouldn't be namespaces" - I do think this is strongly support by the fact:
type members can be manipulated (listed, iterated over, mapped over)
the syntax for accessing a type member is "second-class" - Foo['a'] rather than Foo.a - the latter of which matches property access syntax for values, which IMO makes it more intuitive - hence, "first-class".
Activity
aluanhaddad commentedon Dec 23, 2016
If this is supported, it seems like it should work for the
importstatement as well so that one may acquire both the type and value space meanings if desired.shlomiassaf commentedon Dec 31, 2016
Another annoying thing is the
expected variable-declaration to have a typedeflint rule.We had to suppress it since
const { NavLink, NavGroup } = MyNamespace;had no type...so
import { NavLink, NavGroup } = MyNamespace;will solve that.cchamberlain commentedon Feb 1, 2017
This would be a great feature to have. Looks like general users are struggling with this as well: http://stackoverflow.com/questions/31394725/typescript-destructuring-alias-import
cchamberlain commentedon Feb 1, 2017
An interim that might make sense on the way to type alias destructure might be support for type aliases for namespaces:
Logic for this is that ES supported the above assignment of variables prior to being able to destructure.
tjpalmer commentedon Oct 10, 2017
I was hitting this today. Would be fantastic.
djansyle commentedon Sep 24, 2018
Encountered this scenario this day.
bySabi commentedon Jan 22, 2019
I had been using typescript
importin place of ES6 imports in order of be more explicit on what is a type a what is javascript.Ex:
Would be nice to have destructuring for type imports just like ES6 imports.
Ex:
Any Roadmap for this feature or never be?
OliverJAsh commentedon Jan 22, 2019
Aliasing is problematic when the type to be imported has generics:
bySabi commentedon Jan 23, 2019
your are right!
Probably, aliasing with generics is what stop any move on this.
ashmind commentedon Apr 1, 2020
Would be cool to destructure tuple types as well:
seeruk commentedon Jun 14, 2020
Would love a way to get around this; one practical example where I'm experiencing this is when using the output from protobuf.js's pbjs and pbts tools. They use namespaces, and you can end up with a huge list of imports at the top of the file that could be a lot more compact.
monolithed commentedon Jul 22, 2020
Some examples:
Sheetal Nandi (@sheetalkamat), maybe you know, is there an active discussion of similar feature?
JCMais commentedon Feb 2, 2021
I've been hitting this limitation.
With a monorepo it's hard to use types that are not exported by the main file of an internal package.
voodooattack commentedon Mar 29, 2021
Ran into this today. I'm writing a tool that exports tables/types from PostgreSQL to TypeScript definitions and I'm forced to generate namespaces (in order to avoid name collisions across schemas).
I feel that namespaces are not first class citizens because of this limitation making them too unwieldy.
I'd love to be able to do:
Instead of what I'm doing right now:
Nokel81 commentedon May 26, 2021
Another option would be to allow the following syntax:
This would shorten
MyNamespace.Foo.MyTypeto justFoo.MyTypeBagel03 commentedon Sep 11, 2021
This would make it so much easier to get types from namespaces, especially in instances where you are exporting a class and destructing it only grabs the value. (Ran into this today)
shellscape commentedon Jan 20, 2022
5 Years
That's how long this has been open. Is there any possibility of comment from maintainers as to why this hasn't been addressed?
RyanCavanaugh commentedon Jan 20, 2022
Andrew Powell (@shellscape) pretty much everything TypeScript could possibly ever do was suggested at one point within the first two years of its release, which was about 10 years ago. Needless to say, in that timeframe, we have not done every possible thing, nor could/should we have. C++ is nearing 40 years old at this point and is still adding new features. You'll need to readjust expectations around how fast a language can responsibly add features, unfortunately.
shellscape commentedon Jan 20, 2022
Ryan Cavanaugh (@RyanCavanaugh) I think you're conflating expectations of execution with expectations of comment. it is not unreasonable to suggest that an issue 5 years old should get at least one comment from a maintainer.
I can't figure out if it's unfortunate or hilarious that the only comment this issue received from a maintainer, especially the Development lead for the TypeScript team at Microsoft. was to scold a user who pointed out the lapse of activity by the maintainers of the project on the issue. Whether or not you feel my cheeky reply was in poor taste, that's a bad look.
RyanCavanaugh commentedon Jan 20, 2022
That's valid, and I'm not trying to scold you. We have thousands of open suggestions and if we were going around keeping every suggestion "fresh", we'd do nothing else.
Anyway, concerns I see here:
To expand on the latter, a few different examples were cited in-thread
Notably, Set 1 and Set 2 propose different behaviors for how this should work. In Set 1, the requested operation is
T["n"](property lookup), in Set 2, the requested operation isT.n(namespace access). We can't pick and choose here because forTandn, there might be meanings for both.RyanCavanaugh commentedon Jan 20, 2022
OT: Apologies that I came off that way! "This has been open X years" is a frequent form of unproductive complaining and it sets me on edge whenever I see it, but your request was valid. I can do better and will try to.
shellscape commentedon Jan 20, 2022
Both replies are very much appreciated.
voodooattack commentedon Jan 21, 2022
Hey, just wanted to say we appreciate all the hard work you guys are doing! There's no place for negativity in open source development. Nobody has the right to throw around blame. That's a dangerous mindset and anyone wanting a feature bad enough to complain about it can add it themselves and make a PR. (or even make their own fork if there's a disagreement)
I propose a disambiguation syntax for this:
Here we're explicitly stating that we want to destructure the members of Foo as a namespace and not as a type. TypeScript can expect Foo to be a namespace and throw an error if it isn't.
somebody1234 commentedon May 3, 2022
re: Set 1 - I believe it is not needed whatsoever since what it's really doing is treating a type as a namespace. Destructuring types is a mistake - the only reason one should use the property access operator is for complex generic types, and well... you can't use that syntax in generic types.
... well actually, multiple property access is already possible in generic types so that shouldn't be an issue.
re: "it's purely sugar" - sure. but it's extremely useful sugar that removes a ton of visual clutter.
edit: elaborating on "types shouldn't be namespaces" - I do think this is strongly support by the fact:
Foo['a']rather thanFoo.a- the latter of which matches property access syntax for values, which IMO makes it more intuitive - hence, "first-class".somebody1234 commentedon May 3, 2022
Anyway, at the very least I think getting something like:
should be relatively unambiguous, and there should be zero problems with "better use of this syntactic space" here.