Is it possible to have a synchronous function imported in typescript?

// addons.ts

export interface addon {
  name: string;
  desc: string;
  run: (someparam: any) => void;
}

export function loadaddons(): Array<addon> {
  let addons: Array<addon> = [];
  fs.readdirSync(path.join(__dirname, "addons"))
    .filter((file) => file.endsWith(".js"))
    .forEach((file) => {
      import(path.join(__dirname, "addons", file)).then((imported) => {
        addons.push({
          name: imported.addonInfo.name,
          desc: imported.addonInfo.desc,
          run: imported.startAddon,
        });
      });
    });
  return addons;
}


// index.ts

import { loadaddons } from "./addons";
let addons = loadaddons();
addons.forEach((addon) => {
  addon.run("someparam");
});


// example addon

export const addonInfo = {
  name: "exampleaddon",
  desc: "an example addon",
};

export function startAddon() {}


// output

[]


// wanted output

[
  {
    name: 'exampleaddon',
    desc: 'an example addon',
    run: [Function: startAddon]
  }
]

There is an issue regarding the asynchronous behavior of the import() function. The function does not wait for all addons to be imported and added before returning, causing incomplete results. Here is how I want the process to run:

  • Read directory
  • Filter files with .js extension
  • Cycle through each file asynchronously
    • Import addon
    • Add info to addons variable
  • Return the complete addons array

Note that I am new to TypeScript.

Answer №1

Working with asynchronous functions in TypeScript can have a "contagious" effect on your code. Once you introduce an asynchronous section in a pipeline, the rest of the pipeline usually needs to be made asynchronous as well. While this may not seem ideal at first, there are tools available to help manage asynchronous functions effectively.

If you want to convert your loadaddons function to be asynchronous, you need to consider updating its type signature. Instead of returning an Array<addon>, it will now return a

Promise<Array<addon>>
. Therefore, the new signature will look something like this:

function loadaddons(): Promise<Array<addon>> {
  // ... code to be updated
}

To make the function execute asynchronously, you can transform the existing code into a series of asynchronous actions or steps. One way to do this is by replacing synchronous functions like readdirSync with their asynchronous counterparts such as readdir. By utilizing the promisify function from the 'util' module, you can easily convert callback-based functions into promise-based functions.

For example, you can rewrite a section of your code like this:

import { promisify } from 'util';

promisify(readdir)(path.join(__dirname, 'addons'))
  .then(fs => fs.filter(f => f.endsWith('.js')))

This transformation allows you to handle asynchronous operations more gracefully and efficiently within your codebase. By following similar patterns for other sections of your code, you can create a fully asynchronous workflow that handles promises effectively.

Additionally, it's recommended to adhere to certain conventions when naming interfaces, functions, and data types. For instance, using PascalCase for interface names and camelCase for function names helps maintain consistency and readability in your code.

By making these adjustments and applying best practices, you can enhance the clarity and maintainability of your TypeScript code. Hopefully, these tips will prove helpful in optimizing your asynchronous functions!

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

Troubleshooting problem with fetching data from Angular API

Looking to use Angular to extract a specific value from the following API: Current code snippet being utilized: app.controller("api", function($scope, $http) { $scope.home = "This is the homepage"; $scope.getRequest = function() { console. ...

Incorporating a swisstopo map from an external source into an Angular

I am looking to integrate a swisstopo map into my angular 8 app. As I am new to angular, I am unsure how to include this example in my component: I have tried adding the script link to my index.html file and it loads successfully. However, I am confused a ...

How can one retrieve the selected value from a dropdown menu in Angular?

Objective: My goal is to create a dropdown menu where users can select a value, which will then dynamically change the address of the website based on their selection. Issue: Although I managed to make the address change upon selection, it did so for ever ...

Type guards do not work properly on a union of enum types in TypeScript

Recently delved into the concept of Type Guards Chapter within the realm of Typescript However, I encountered an issue where my basic type guards failed to differentiate a union of enums. Why is this happening? enum A { COMMA = ',', PLUS = & ...

Error encountered when attempting to utilize Path Aliases in Angular 11.tsconfig

Currently, I am working on a project using Angular 11 and aiming to utilize short imports like import {smthg} from '@common' instead of import {smthg} from '../../../common' However, I keep encountering errors in IDEA: TS2307: Cannot f ...

What is the proper way to indicate the pointer to the current element within the array?

How can I modify a code that displays a list of posts? import React from "react"; type respX = { "id": any, "userId": any, "title": any, "body": any, } interface PropsI { } interface StateI { data: respX []; } export class Compone ...

HTML: Mark the chosen hyperlink or tag

In my HTML page, I am looking to keep the link selected when it is clicked on. Here is the initial HTML code: <table class="main-dev"> <tr> <td> <a class='titleForm' style="cursor:pointer"> ...

Dynamic module declaration - Typescript 3.5

In TypeScript, I am able to declare a module like this: declare module '*.svg' { const content: string export default content } After declaring the module, I can import it using import svg from './src/file.svg' without encount ...

What is the reason that control flow analysis does not support the never type?

Here is the scenario I'm dealing with (utilizing strictNullChecks): function neverReturns(): never { throw new Error(); } const maybeString: string | null = Math.random() > 0.5 ? "hi" : null; if (!maybeString) { neverReturns(); // th ...

Ways to invoke the function in a separate component

How can I use ViewChild to call a method in a different component? I have a method in the piechart component that I want to access from the app component using ViewChild. In my piechart.component.ts file: export class PiechartComponent { constructor() ...

What is the process for applying cdkDropList to the tbody when using mat-table instead of a traditional HTML table?

I have been experimenting with the mat-table component in my Angular project, following a simple example from the documentation: <table mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <!--- These columns can be ...

Tips for determining if an array of objects, into which I am adding objects, contains a particular key value present in a different array of objects

I've been working on this and here is what I have tried so far: groceryList = []; ngOnInit() { this._recipesSub = this.recipesService.recipes.subscribe((receivedData) => { this.loadedRecipes = receivedData.recipes; }); } onCheckRecipe(e) { ...

When using Typescript inheritance, the datatypes shown in IntelliSense are unexpectedly listed as "any" instead of

In my Typescript code, I have a small implementation where a class is either implementing an interface or extending another class. interface ITest { run(id: number): void } abstract class Test implements ITest { abstract run(id); } class TestEx ...

Customizing pressed row styles and properties within a map iteration in React Native

How can I modify the style of a single item in a list when a button is pressed in React-Native? I want only the pressed item to change, not the entire row. Here is my attempt at implementing this: //hooks const [activeStyle, setActiveStyle] = useState( ...

"Implementing an abstract method in a class by overloading it with a generic type that

// Greetings from the TypeScript Playground, a platform where you can experiment with TypeScript code. type Constructor<T> = new (...args: any[]) => T; class ServiceChecklistResponse { } class AnotherModel { } abstract class AbstractView { ...

Error TS2322: Type 'Partial<T>' is not assignable to type 'T'

I'm struggling to articulate my problem, so I think the best way to convey it is through a minimal example. Take a look below: type Result = { prop1: { val1: number, val2: string }, prop2: { val1: number } }; f ...

Having trouble running `npm start` on my NodeJs project

Hi everyone, I could really use some help with the npm start command. I am currently working on a Node.js project with TypeScript on Windows 7-64, but I'm encountering errors when trying to start it. If you can assist, please check out the following ...

Retrieving specific properties from a JSON object and logging them

I am attempting to access JSON Object properties directly and log them using the following function : loadProcesses(filter?){ this._postService.getAllProcess(filter) .subscribe( res=> { this.processListe = res; // console.log(this.p ...

What is the appropriate interface for determining NavLink isActive status?

In the process of crafting a "dumb" component using NavLink, I am defining the props interface for this component. However, I encountered an issue when trying to include isActive in the interface. It's throwing errors. I need guidance on how to prope ...

Loading an Angular2 app is made possible by ensuring that it is only initiated when a DOM element is detected

In my main.ts file, the code below is functioning perfectly: import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app.module'; platformBrowserDynamic().bootstrapModule(AppModule); H ...