Can an "interface" be created to accept class instances without knowing their type or implementation in advance?

As a beginner in the world of dart, I recall how in typescript I was able to structure my code like this:

// business-logic.ts

interface Item { name: string; }

interface Repository {
  addItem: (item: Item) => Promise<void>;
}

export class BusinessLogic {
  private repo: Repository;

  constructor(repo: Repository) {
    this.repo = repo;
  }

  async doSomething() {
    await this.repo.addItem({ name: 'apple' });
  }
}
// repo.ts

export class Repository {
  async addItem(item: { name: string }) { /* impl */ }
}
// runtime.ts
import { BusinessLogic } from './business-logic';
import { Repository } from './repo';

const logic = new BusinessLogic(new Repo());

This method allowed for clear definition of dependencies in business logic while maintaining separation between types and implementations. Is there a similar approach in dart, or is defining an abstract class Repository in business logic the only way forward?

Answer №1

While JavaScript is a dynamically typed language and TypeScript acts as a development-level superset of it, the concept of interfaces in TypeScript differs from those in Dart. In TypeScript, interfaces serve as a blueprint for JavaScript objects to follow at compile time, rather than as strict contracts. This means that errors are caught during compilation if the object does not adhere to the interface.

On the other hand, Dart, being strongly-typed, enforces interfaces with class definitions, creating rigid contracts. In Dart, classes must explicitly implement interfaces before they can be used.

// business_logic.dart

abstract class IItem {
  String item;
}

abstract class IRepository {
  Future<void> addItem(IItem item);
}

class BusinessLogic {
  Repository _repo;

  BusinessLogic(this._repo);

  void doSomething() async {}
}

In Dart, interfaces are defined using abstract classes, denoted by names starting with "I". The implementation process involves defining separate classes that conform to these interfaces, wherein syntactic differences come into play.

// repo.dart

class Item implements IItem {
  String item;
}

class Repository implements IRepository {
  Future<void> addItem(IItem item) async {
    /* impl */
  }
}

Similarly, Dart requires explicit implementation of interfaces through classes like Item and Repository. Once again, syntactic variations come into play, emphasizing the necessity of adherence to interface specifications.

(It's worth noting that in TypeScript, there may be instances where the code references structures instead of actual interfaces, potentially leading to errors. Unlike Dart's strong typing system, such issues might go unnoticed until runtime.)

// runtime.dart

import './business_logic' show BusinessLogic;
import './repo' show Repository;

final logic = BusinessLogic(Repository());

The final step involves bringing everything together in runtime. Syntax remains key here, with mentions of selective imports reflecting similarities between TypeScript and Dart, even though Dart doesn't require the same level of specificity.

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

Disabling ESLint errors is not possible within a React environment

I encountered an eslint error while attempting to commit the branch 147:14 error Expected an assignment or function call and instead saw an expression @typescript-eslint/no-unused-expressions I'm struggling to identify the issue in the code, even ...

Troubleshooting image loading issues when updating the base URL in an Angular JS project

I am trying to update the base URL for my application. Currently, when I load the application, the URL shows up as http://localhost:4200/#/, but I want it to be http://localhost:4200/carrom/ instead. To accomplish this, I modified the base URL and now th ...

Is it possible to access NgbdModalContent properties from a different component?

If I have a component with a template containing an Edit button. When the user clicks on it, I want to load another component as a dynamic modal template. The component is named ProfilePictureModalComponent and it includes the Edit button: (Angular code h ...

Attempting to utilize Pinia without a corresponding component will result in an error indicating that there are no

In my Vue.js 3 project using the ViteSse template, I encountered an issue when trying to access my Pinia store named notificationStore outside of the setup component. When running the dev command, I received an error message saying "getActivePinia called w ...

Angular 6 data modification update: What you need to know

Whenever a new response is added to the array of 15 responses, I aim to dynamically update the view without requiring the page to refresh. addResponseToItemArray(res: DashboardInfo[]): void { this.item.push([]); // ERROR this.item.push([]); ...

The error message "TypeError: The object prototype can only be an Object or null: undefined in Angular"

When trying to launch my web app using 'ng serve', I am encountering an error that I cannot seem to resolve. The error message is quite cryptic, and despite updating dependencies and searching through similar questions, I am still unable to pinpo ...

Setting up CORS for Azure Active Directory

My goal is to programmatically obtain an access token from Azure Active Directory in an Angular 6 application using the method below. let body1 = new FormData() body1.append("resource", environment.config.clientId) body1.append("grant_type", " ...

The JSX element 'HeaderPublic' does not contain any construction or calling signatures

I am currently utilizing nx workspace to build the react ts application. Below is the library component: import { ReactElement } from 'react'; import styles from './header-public.module.scss'; export function HeaderPublic(): ReactElem ...

When using ngFor in HTML, the ID of an object within an array of objects can become undefined during execution

Currently, I am in the process of developing a mobile application with the Ionic framework. One of the key functionalities of this app involves making an API call to retrieve transaction data, which then needs to be displayed in the HTML template: The dat ...

Exploring the differences between Typescript decorators and class inheritance

I find myself puzzled by the concept of typescript decorators and their purpose. It is said that they 'decorate' a class by attaching metadata to it. However, I am struggling to understand how this metadata is linked to an instance of the class. ...

How can I convert an object to JSON using JSON.stringify and ensure its type is recognized as JSON?

When I attempt the following code snippet: import { MyType } from 'somewhere'; class MyClass { myObj: MyType = new MyType(); updateObject(newVal: string): void { myObj.thing = newVal; this.saveStuff(JSON.stringify(myObj ...

Error: Unable to instantiate Razorpay as a constructor

Having some trouble integrating Razorpay with Node TypeScript. The issue appears to be related to the const variable razor. Any help or insights would be greatly appreciated. Thank you! import * as Razorpay from 'razorpay'; const razor = new ...

I'm having trouble asynchronously adding a row to a table using the @angular/material:table schematic

Having trouble asynchronously adding rows using the @angular/material:table schematic. Despite calling this.table.renderRows(), the new rows are not displayed correctly. The "works" part is added to the table, reflecting in the paginator, but the asynchron ...

Timing the loop iteration before passing the value to the function included

I'm currently exploring how to implement a timeout for a function within a loop iteration in an Ionic application using TypeScript. setInterval will execute the function at equal time intervals in a continuous loop: setInterval(() => { th ...

Can a new record be created by adding keys and values to an existing record type while also changing the key names?

If I have the following state type, type State = { currentPartnerId: number; currentTime: string; }; I am looking to create a new type with keys like getCurrentPartnerId and values that are functions returning the corresponding key's value in Sta ...

Angular 5 experiencing issues with external navigation functionality

Currently, I am attempting to navigate outside of my application. I have experimented with using window.location.href, window.location.replace, among others. However, when I do so, it only appends the href to my domain "localhost:4200/". Is it possible th ...

Continuously converting methods recursively until the array is fully processed

My current code has a method that is not very efficient and does not scale well. The object y is an array consisting of key/value pairs, each containing two properties: 1. A unique string property called name. This value is identified by the childre ...

Showing json information in input area using Angular 10

I'm facing an issue with editing a form after pulling data from an API. The values I retrieve are all null, leading to undefined errors. What could be the problem here? Here's what I've tried so far: async ngOnInit(): Promise<void> ...

Perform validation for a form field in Angular 2 asynchronously by making an HTTP request

I have a concept where the user can submit a form and if the email is already registered, an error triggered by the API should display. I am using reactive forms with FormBuilder and trying to implement the validator in the subscribe error handler. Constr ...