The unspoken rules of exporting and importing in TypeScript

In comparison to Java (as well as other programming languages), TypeScript provides multiple options for exporting and importing entities such as classes, functions, etc.
For instance, you have the ability to export numerous classes, constants, functions, etc. in a single file.
Furthermore, it is possible to define one default export per file.
Conversely, when it comes to importing, you can only import the default export, import everything using an alias, or import specific elements.
As someone coming from a Java background, I am curious if there are any conventions to follow, especially concerning constants and functions.
Let's consider a scenario where I have a utility file containing several functions. In Java, I would typically create a Util.java file with a class Util that encompasses all the static functions.
In TypeScript, there are two main approaches:

  1. Export each function individually and import them 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(), similar to how it is done in Java.

Another scenario involves a class with some constants. For example, let's say I have a class Car with a field named type. There are also constants representing different available types such as TYPE_SUV, TYPE_SPORT, and so on.

Once again, I can declare these as "top-level" constants, export them along with the Car class. Alternatively, I could define them as public static readonly within the Car class and export only the class itself.
Opting for the first approach may result in a lengthy import statement when needing all constants in other files. Additionally, sub-classes would not automatically inherit these constants.
However, utilizing readonly instead of const might seem unconventional to some.

While seeking a standard convention, I didn't come across many resources regarding exports and imports in TypeScript, specifically addressing the aforementioned challenges. The few tips I did find were limited like this.

Therefore, are there established guidelines governing exports and imports in TypeScript that address these issues effectively? I am also interested in determining the best practices for tool integration (e.g. refactoring, auto-importing, organizing imports, etc.).

Thank you.

Answer №1

(While there are objective elements in choosing one method over another, the following may have some opinion-based aspects)

  1. My preferred approach is to export every single function and import them using import * as Util.
  2. Alternatively, you can create a class called Util with static functions and export only this class.

I tend to favor the first option because the second does not offer any significant benefits and could potentially lead to unnecessary instantiations of the Util class (unlike Java where this can be prevented).

Another consideration is whether to define constants as "top-level" exports along with the Car class or as public static readonly properties within the Car class which is then exported alone.

It's worth noting that the readonly modifier for constants applies only at compile time, allowing them to still be modified at runtime when used as class properties. For this reason, I prefer to define constants as top level exports in the module (file).

In alignment with Basarat's excellent handbook, I also agree on the limited utility of default exports which often just add confusion. Instead, with named exports, it's possible to rename imports as needed e.g.

import { OriginalName as MyPreferredName} from './OriginalName'

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: `$(...).fullCalendar is not a function` when using React

After scouring through multiple posts discussing similar issues, I've noticed a common theme of problems arising from improperly loading jQuery or fullcalendar. However, in my case, I have both components loaded into my code (although I can't be ...

How to open a print preview in a new tab using Angular 4

Currently, I am attempting to implement print functionality in Angular 4. My goal is to have the print preview automatically open in a new tab along with the print popup window. I'm struggling to find a way to pass data from the parent window to the c ...

Removing an item from a table row cannot be completed due to the inability to retrieve the list_body ID necessary for deletion

I have been working on enhancing the delete button function in my table. The id linked to the list_body must be incorporated into the delete function code. I utilized some jquery methods to render the list onto the webpage. //retrieve user list information ...

The new pop-up window appears smaller than expected in Internet Explorer

There has been a bug report regarding the course opening in a smaller popup window. The JavaScript code used to open the popup is: course_window=window.open(urlString,"", "toolbar=0,directories=0,location=0,status=0, menubar=0,fullscreen=0,scroll ...

The concept of variables within the jQuery each function

Can someone provide assistance? I want the variables id, zIndex, and width inside the function to be defined after jQuery.each is called, with their values coming from the array passed to the function MyFunction: console.log(id); //ID IS NOT DEFINED con ...

Looking to determine if two elements exist within an array? Seeking a boolean result based on their presence

Consider the following array of objects: quesListArray = [ { QuestionTypeID : 1, QuestionTypeName : 'Rating' }, { QuestionTypeID : ...

Flatten a specific property of an object recursively

If I have a data structure containing nested objects, I need to create a type that removes specific keys and flattens certain fields recursively Input: { sys: { id: string; }; metadata: { author: string; }; fields: { ...

Changing the Id in Angular 2 Routing: A Step-by-Step Guide

Currently, I am working on an Angular 2 project with routing implementation. In the app.routing.module.ts file: { path: '', component: CComponent }, { path: 'Ddata:id', component: DComponent, children: [ { path: &apo ...

Converting a string into an object using JavaScript

How can I transform the following string into an object? {src:'img/testimage.jpg', coord : {x:17, y:39}, width:200, height, 200} Update: I have a PHP file that generates JSON output. I used AJAX to retrieve the JSON in my JavaScript. By using ...

Ways to automatically close the external window upon logging out in Angular 12

I have successfully created an external window in my Angular application. Everything is working as expected, but I am facing an issue when trying to automatically close the external window upon user logout. Although I have written the code below and it wo ...

I encountered an error with no matching overload when attempting to make a call using the Tanstack query function

While I was successfully calling a single data in my database using the useEffect hook, now I am attempting to learn how to use tanstack@query. Unfortunately, I encountered an error when trying to call it. No overload matches this call. Overload 1 of 3, ...

Sending data from a dynamically created PHP table to a modal

In my PHP-generated table, I have: <tbody> <?php $results = DB::select()->from('users')->execute(); foreach ($results as $user) { echo "<tr id='".$user['id']."'> <input type=&bs ...

Only the element that was clicked will have its state updated

My current code looks like this: export default class MyClass extends Component { constructor(props) { super(props); this.state = { data: [ {id: 101, name:"One", thevalue:11}, {id: 102, name:"Two", thevalue:22}, ...

Issue with template updating when utilizing ui-router and ion-tabs in Ionic framework

CODE http://codepen.io/hawkphil/pen/LEBNVB I have set up two pages (link1 and link2) accessible from a side menu. Each page contains 2 tabs: link1: tab 1.1 and tab 1.2 link2: tab 2.1 and tab 2.2 To organize the tabs, I am utilizing ion-tabs for each p ...

Implementing many-to-many relationships in JPA/Hibernate can be done when the join table has its own primary key

I have a scenario with three tables of simple structure: pub [id, name] days [id, name] pub_days [id, pub_id, days_id] Interestingly, someone decided to add their own primary key to the pub_days table in addition to the compound identity (pub_id + days_i ...

Which Angular tools should I be using: map, pipe, or tap?

When my component initializes, I retrieve data from the server import {Rules} from "../../interfaces/interfaces"; rules: Rules ngOnInit() { this.tt = this.rulesService.getUserClientRules().subscribe( t => { console.log(t) con ...

The node application route appears to be malfunctioning

Recently delving into the world of node JS, I encountered an issue while working on my application with the following 3 files. http.createServer(app).listen(**app.get('port')**, function(){ The error message reads 'undefined is not a func ...

Bootstrap Popover not displaying information after an AJAX request

I'm struggling to update the popovers contents with Ajax result in my ASP.Net MVC4 project. Using ASP.Net (MVC4): public ActionResult GetEmployeeDetails(string employeeId) { var contract = UnitOfWork.ContractRepository.ContractBu ...

Examining the array to ensure the object exists before making any updates in the redux

Is there a way to determine if an object exists in an array and update it accordingly? I attempted to use the find method, but it couldn't locate the specified object. I also tried includes, but it seems to be unable to recognize the item within the ...

Efficient management of jQuery variables

I am currently working on a form and I have been trying to change an input's type using jQuery. Thanks to the helpful resources available on this website, I learned that I need to clone and replace the input in order to change its type. However, I enc ...