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
{{ message }}
Repository navigation
type-only import prevents declaration of a value with the same name #40583
Search Terms:ts1361type-onlyimport type'Foo' cannot be used as a value because it was imported using 'import type'.
Code
importtype{Foo}from"./Foo";functionFoo(): Foo{return{name: "index.ts"};}Foo();// 'Foo' cannot be used as a value because it was imported using 'import type'.ts(1361)
Expected behavior: Since the import type only creates a symbol in the type realm, I expect to be able to create the same symbol in the value realm without conflict. Especially since it's possible to declare the same symbol as both a type and value from within a single file.
Actual behavior: An error is raised: 'Foo' cannot be used as a value because it was imported using 'import type'.ts(1361), which makes this behavior seem very much intended, though that seems to violate the feature's stated intent. From the description of the feature's Type semantics from #35200:
If the symbol does have a value side, name resolution for that symbol will see only the type side.
Sorry for bringing this up after four years, but I'm interested in what way can Foo still be a value if we've explicitly imported it as a type, and there's no e.g. value of the same name as the type in the imported module?
The best way to understand this is that the correct interpretation isn't "Import the type meaning of Foo", it's "Import Foo for use in type positions". For example, let's say you have a class exported in one file
// foo.tsexportclassFoo{staticx="bar";}
You can import it elsewhere and use it as a value, in type positions:
importtype{Foo}from"./foo.js";functionsomething(f: typeofFoo){// <- *value* reference on Fooreturnf.x;}
Aha. So this is more a feature for avoiding unnecessary imports in the built code. If I want to use a value Foo just to get it's type, then I use import type and I can use the value only on the type position, and this value won't actually be included in the final built JS.
Activity
DanielRosenwasser commentedon Sep 16, 2020
This is correct,
Foostill potentially refers to a value which can only be used in non-emitted positions. If you want to separate the two, consideror
DanielRosenwasser commentedon Sep 16, 2020
Letting Andrew Branch (@andrewbranch) correct me if I'm mistaken though
andrewbranch commentedon Sep 16, 2020
You got it right 👍
typescript-bot commentedon Sep 18, 2020
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
mastarija commentedon Aug 1, 2024
Sorry for bringing this up after four years, but I'm interested in what way can
Foostill be a value if we've explicitly imported it as a type, and there's no e.g. value of the same name as the type in the imported module?RyanCavanaugh commentedon Aug 1, 2024
The best way to understand this is that the correct interpretation isn't "Import the type meaning of
Foo", it's "ImportFoofor use in type positions". For example, let's say you have a class exported in one fileYou can import it elsewhere and use it as a value, in type positions:
mastarija commentedon Aug 1, 2024
Aha. So this is more a feature for avoiding unnecessary imports in the built code. If I want to use a value
Foojust to get it's type, then I useimport typeand I can use the value only on the type position, and this value won't actually be included in the final built JS.