2

In contrast to Java (and other languages), TypeScript offers you multiple ways to export and import things (classes, functions etc.).
For example, you can export multiple classes, constants, functions etc. per file.
Also you can define 1 default export per file.
On the other side you can import only the default export, import everything using an alias or import the given things.
Coming from Java, I wonder, if there is any convention, especially regarding constants and functions.
Let's say I have a util-file, having a lot of functions. In Java I would create a File Util.java with class Util, which contains all the static functions.
In TypeScript I have following possibilities:

  1. Export every single function and import it using import * as Util.
  2. Create a class Util with static functions and export only this class.

In both cases I can call functions using Util.functionName(), just like in java.

Another case is a class with a few constants.
For example I have a class Car with a field type. There are also constants for the available types, like TYPE_SUV, TYPE_SPORT and so on.

Again, I can define them as "top-level" constants and export them and the class Car. But I can also define them as public static readonly inside the Car-class and export that class only.
Using the first approach, I would have a verry big import statement, if I need all constants in other files. Also sub-classes won't "inherit" those constants.
However using readonly instead of const feels kind of strange to me...

So I was looking for some kind of convention, but I did not find much.
I only found a few tips like this.

So, are there any guidelines regarding exports and imports in TypeScript, which take care about the explained problems? I am also looking for the best way, regarding integration of tools (refactoring, auto-importing, organizing imports etc.).

Thanks.

4
  • Java also has import static package.Util.functionName, by the way, for static methods and variables. In both cases importing a subset of what's available initializes both namespaces fully (class and js-file respectively). Other than that, answer to this lies in some place with whether you indent you code with tabs or spaces, and how much of each of those a good programmer needs in their life. Commented Mar 10, 2017 at 16:47
  • @M.Prokhorov thanks for your opinion. You are right about import static, however it seems to be rarely used. As I am pretty new to TypeScript I don't have a preference on that yet, so I wanted to choose the thing, that tools (IDEs, Editors etc.) like the most. For example default exports seem to cause problems with refactoring. Commented Mar 10, 2017 at 16:52
  • I started to use static imports a lot more when Hamcrest and Java 8 came along, personally, because stream.collect(Collectors.toList()) is a little shorter without Collectors in the middle. As for tool and refactoring, - it at least looks to me that there is more than one way to express same import in JS, so tools get confused, but tools will eventually catch up anyway. You should choose what's better for you to read, not for machines. Commented Mar 10, 2017 at 17:10
  • In the perfect case, I wouldn't even need to read the imports as they are fully managed by the tools. In eclipse with java, I never need to take care about the import. I use organize imports and everythig is fine Commented Mar 10, 2017 at 17:26

1 Answer 1

1

(I am afraid this is going to be somewhat opinion based although there are objective elements in choosing one over another)

  1. Export every single function and import it using import * as Util.
  2. Create a class Util with static functions and export only this class.

I prefer number 1) because 2) does not bring any benefit and may lead to someone instantiating the Util class for no reason (and contrarily to Java, this cannot be prevented).

I can define them as "top-level" constants and export them and the class Car. But I can also define them as public static readonly inside the Car-class and export that class only.

With regards to constants, the readonly modifier only applies at compile time. So as class properties, they can still be modified at runtime. I, hence, prefer to make them top level constants in the module (file)

The excellent handbook from Basarat is also my "reference" and I share his opinion on default exports which do not bring much aside from confusion since with named exports, it is also possible to rename on import e.g.

import { OriginalName as MyPreferredName}  from './OriginalName'
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your opinion! The benefit of creating a class Util would be, that the imports look the same everywhere. Also I am a bit afraid of tooling (like rename the function, would it be renamed in Util if i import * as Util?). Also with the constants I have the problem, that I need to import 10+ constants or write import * as XYZ. That makes it imposible to use classname.constant, as I would do in java.
I understand.. but this not Java :) (I program in both too). Things are less "constant" and "final" in the JS world, so I prefer the safe side to good looking imports. Now 1) you can have named imports: import {myFunction} from './Util' rather than namespacing everything wih import * as ns and 2) my IDE (IDEA) is good at refactoring; some devs here use VSCOde, which looks good at it too
Okay. Thanks again for your opinion. One last thing: Do you usually preffer to import every single thing of a file (if there are many) or import everything using * ?
I prefer to import every single element in order to avoid the namespace i.e. I prefer to write myImportedFunc to util.myImportedFunc. When there are names conflicts it is possible to rename named exports on import i.e. import {conflictingName as otherName} from './Myfile'
Thanks for your opinion. +1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.