Is it possible to add functionality to Interfaces in TypeScript?

In my software development project, I am working with an Interface and I want to create computed properties that rely on other properties within the interface.

For instance, the Person interface includes properties for first name and last name. How can I enhance the Person interface so that it includes a new property called fullName, which combines the values of the first name and last name properties for all implementors?

interface Person {
  firstName: string;
  lastName: string;
}

class Pilot implements Person {
     constructor(public firstName: string, public lastName: string) {}
}

class Sailer implements Person {
     constructor(public firstName: string, public lastName: string) {}
}

const pilot = new Pilot("Joe", "Alpha")
const sailer = new Sailer("Jane", "Beta")

// How can I extend `Person` interface to include fullName property?

console.log(pilot.fullName) // Joe Alpha
console.log(sailer.fullName) // Jane Beta

Answer №1

My approach would be to continue with the parent class in this scenario

interface IPerson {
  firstName: string;
  lastName: string;
}

class Person implements IPerson {
  constructor(public firstName: string, public lastName: string) {}

  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

class Pilot extends Person {}

class Sailer extends Person {}

const pilot = new Pilot("Joe", "Alpha")
const sailer = new Sailer("Jane", "Beta")

console.log(pilot.getFullName())
console.log(sailer.getFullName())

You can check out the demo here.

Answer №2

If you want to add a fullName property to the Person interface, one approach is to implement it using a getter method:

interface Person {
  firstName: string;
  lastName: string;
  fullName: string;
}

class Driver implements Person {
  firstName: string;
  lastName: string;

  constructor(firstName: string, lastName: string) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
}

class Diver implements Person {
  firstName: string;
  lastName: string;

  constructor(firstName: string, lastName: string) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
}

const driver = new Driver("John", "Doe");
const diver = new Diver("Sarah", "Smith");

console.log(driver.fullName); // John Doe
console.log(diver.fullName); // Sarah Smith

Answer №3

In TypeScript, it appears that binding getter functions directly to interfaces is not supported. However, a workaround would be to utilize a parent class named Person that implements the IPerson interface:

interface IPerson {
  firstName: string;
  lastName: string;
}

class Person implements IPerson {
  constructor(public firstName: string, public lastName: string) {}
  public get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

class Pilot extends Person {
  constructor(public firstName: string, public lastName: string) {
    super(firstName, lastName);
  }
}

class Sailer extends Person {
  constructor(public firstName: string, public lastName: string) {
    super(firstName, lastName);
  }
}

const pilot = new Pilot("Joe", "Alpha");
const sailer = new Sailer("Jane", "Beta");

console.log(pilot.fullName); // Joe Alpha
console.log(sailer.fullName); // Jane Beta

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

Option to Exclude Files in Gulp-uncss

I've been trying to use the ignore option, but it doesn't appear to be functioning as expected. My code looks like this: .pipe(plugins.uncss({ html: glob.sync('./**/*.{csh,h}tml'), ignore: ['.active'] ...

Is it possible to access forms and input fields in an AngularJS script without having to pass them from the HTML code?

Seeking a solution for input field validation, I have written code where input field states are passed from HTML to a script through a function. However, my goal is to directly retrieve the values in the script without passing them from the HTML when calli ...

Creating a React TypeScript component that accepts generic props to be passed down to its children

I'm exploring the idea of creating a React component that functions similarly to an Accordion. This component would contain children elements that can be individually opened and closed. Each child element is also a React component, requiring unique pr ...

Issues with Angular routing functionality being experienced

Currently, I am experimenting with Angular routing within my Ruby on Rails application. The issue arises when I navigate to a specific route, such as '/', and have an Angular routing setup to load a template from a designated directory. This tri ...

Having trouble converting svg to png, thinking it might be due to discrepancies in svg elements

I am facing a puzzling issue where two different SVG elements are causing my JavaScript to work in one scenario but not the other. I have replaced the SVG elements in both examples, and surprisingly, only one works while the other does not. You can view th ...

Struggling to maintain data consistency among controllers in Angular by utilizing the rootScope, only to encounter persistent issues with

I am facing an issue with displaying the admin status at the top of all pages for a user who successfully logs in as an admin. Here is my code snippet: <!-- nav bar --> <div> <span ng-show="$root.isAdmin">(ADMIN)</span> </di ...

Leverage the power of jQuery to manipulate video tags

Here's the challenge: I need to utilize a jQuery function to extract a URL from a link's REL attribute and then transfer it to a video element. The extraction process and transmission seem to be working smoothly. However, my struggle lies in act ...

Tips on incorporating jstree into an Angular 2 application with TypeScript and @types/jstree

Hello, I am new to ng2 and have a question that may seem obvious to some. I recently installed the jstree library using npm in my angular-cli application by running the command npm i jstree --save. Following this, I also installed the types for jstree wi ...

The body parser is causing issues with decoding base64 strings

When my mobile app sends a base64 string to my Express server via a POST request, the image is transmitted to a Google client endpoint. However, an error is returned saying: Provided image is not valid code: 400, 0|index | errors: [ 0|index | { 0 ...

Manipulating and passing structures of the same type in class methods

Can you advise on the proper way to write this class? class X { f(): this { return this; } g(): { a: this } { return { a: this }; } h(obj: {a: this}): this { return obj.a; } } Issue encountered in ts playg ...

What is the best way to upload items by utilizing text input and a submission button?

I've been experimenting with loading obj files using three.js and webGL. Currently, I can load one object by directly modifying the code, but now I want to give users the ability to upload their own .obj files. Here is the code snippet that I have so ...

Advantages and Disadvantages of Implementing Ajax for Form Validation

Exploring the benefits of validating forms with Ajax, I find it to be a valuable tool in preventing code redundancy. However, before making the switch, I am curious about any potential drawbacks compared to traditional JavaScript validation. While I have c ...

Ensure there is a gap between each object when they are arranged in a

Is there a way to customize the layout of elements in the ratings view so that there is automatic spacing between them? I considered using text (white spaces) for this purpose, but it seems like an inefficient solution. Are there any other alternatives to ...

The field 'index' is not found in the type 'Ingredient' in Angular 8

I've been following a tutorial to learn Angular with ngrx and I'm having trouble with my action file. Here is how my action file looks: import { Action } from '@ngrx/store'; import { Ingredient } from 'src/app/shared/ingredient.m ...

The classification of a dictionary and a list in Typescript

Can you spot the difference between the two codes below for defining a type of props? I realized that the first one didn't throw a type error, but I can't figure out why my initial second code was incorrect. To me, it seems like it should work p ...

What is the best method to set up separate column filters when using DataTables with serverSide enabled?

I am facing an issue with the search column in my datatable. The problem is that the search functionality doesn't work properly because I am retrieving data from the database in batches of 10 via AJAX when the user clicks on a page number. This means ...

Typescript error code TS7053 occurs when an element is detected to have an implicit 'any' type due to an expression of a different type

I encountered an issue with the provided example. I'm uncertain about how to resolve it. Your assistance would be greatly appreciated. type TestValue = { value: string; }; type FirstTest = { type: 'text'; text: TestValue[]; }; typ ...

Mastering form submission in Vue.js

I have been working on a form that needs to be submitted and stored in a database. I attempted to connect my VueJS application with Firebase in order to insert the data into the database, but unfortunately, I have not been successful. Here is my form: &l ...

save the received data to a new document

How can I pass the data returned from the API below to another function in a separate JavaScript file? This question may be similar to others, but those do not involve working with returned results. Please consider this before labeling it as a duplicate. ...

Set up a loop that retrieves data from an array and dynamically populates the content of my template card component

I am working on a reactjs + typescript component that displays templates: My goal is to pass the template details like title, description, and image using an array. import ActionPageTemplateContainer, { Template } from "./ActionPageTemplateContainer& ...