Extensible generic type/interface in Typescript

Looking to create a versatile base interface or type that can adapt its properties based on the generic object it receives. It might look something like this:

interface BaseObject<Extension extends object = {}>{
   a: string;
   b: string;
   {...Extension} <<< This syntax works in regular objects, but not in this context
} 

const sample:BaseObject<{x: number}> = {
    a: '123',
    b: '123',
    x: 123 <<<< Enforcing a type check here
}

Any ideas on how to implement this?

Answer №1

To achieve this, simply expand the interface.

interface EnhancedObject extends BaseObject {
  y: number;
}

const data: EnhancedObject = {
  a: 'abc',
  b: 'def',
  x: 456,
};

Answer №2

To achieve this functionality, one approach is to utilize mapped types with an Extension. TypeScript does have limitations when it comes to declaring types that use mapped types alongside property types or in an interface declaration. However, you can still create a type that combines the properties of Extension with the base properties by using an intersection, even though the syntax may seem a bit unusual:

type BaseObject<
  Extension extends object = {},
  All = Extension & { a: string; b: string }
> = {
  [K in keyof All]: All[K];
};

It's worth noting that the second generic property isn't strictly required. Alternatively, you could write it in the following manner:

type BaseObject<Extension extends object = {}> = {
  [K in keyof (Extension & { a: string; b: string })]: (Extension & {
    a: string;
    b: string;
  })[K];
};

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

Creating a service in AngularJS 1.8 with ES6 modules that acts as a bridge to a class based API interface

As I continue to enhance a codebase that originally consisted of a mix of different versions of AngularJs and some unstructured code utilizing various versions of a software API, I encounter an interesting quirk. It appears that this API is accessible thro ...

Return the reference to an injected service class from the location where it was implemented

Is it feasible to return a reference from a component class with a custom interface implemented to the injected service class in my Angular 6 project? Here is an example of what I am aiming for. ServiceClass @Injectable() export class MyService { co ...

Angular 14 encountered an unexpected issue: There was an unhandled exception with the script file node_modules/tinymce/themes/modern/theme.min.js missing

After attempting to run ng serve, an error message appears: ⠋ Generating browser application bundles (phase: setup) ...An unhandled exception occurred: Script file node_modules/tinymce/themes/modern/theme.min.js does not exist. ⠋ Generating browser ap ...

The password encryption method with "bcrypt" gives an undefined result

import bcrypt from 'bcrypt'; export default class Hash { static hashPassword (password: any): string { let hashedPassword: string; bcrypt.hash(password, 10, function(err, hash) { if (err) console.log(err); else { ha ...

What exactly does the context parameter represent in the createEmbeddedView() method in Angular?

I am curious about the role of the context parameter in the createEmbeddedView() method within Angular. The official Angular documentation does not provide clear information on this aspect. For instance, I came across a piece of code where the developer i ...

An effective way to define the type of a string property in a React component using Typescript

One of the challenges I'm facing is related to a React component that acts as an abstraction for text fields. <TextField label="Enter your user name" dataSource={vm} propertyName="username" disabled={vm.isSaving} /> In this set ...

Failure to Execute Angular HttpClient Request

I'm facing an issue with firing the HttpClient request. It seems like there might be a problem with importing or providing, but I can't pinpoint where it is exactly. The API works fine, but the call never goes through. Here are the environment/v ...

Setting default selections for mat-select component in Angular 6

I've been attempting to preselect multiple options in a mat-select element, but I haven't been successful so far. Below is the snippet of HTML code: <mat-dialog-content [formGroup]="form"> <mat-form-field> <mat-select pla ...

What is the method for deducing the names that have been announced in a related array attribute

In my definitions, I have identified two distinct groups: Tabs and Sections. A section is encompassed by tabs (tabs contain sections). When defining sections, I want the tab names to be automatically populated by the previously declared sibling tabs. But ...

Mongodb Dynamic Variable Matching

I am facing an issue with passing a dynamic BSON variable to match in MongoDB. Here is my attempted solutions: var query = "\"info.name\": \"ABC\""; and var query = { info: { name: "ABC" } } However, neither of thes ...

Ways to sign up for the activeDate variable in MatCalendar so you can display the month and year labels of the current active date in the

As a newcomer to Angular, I am working on creating a datepicker with a customized header. I have successfully passed a custom header for the mat-calendar component. Reference: https://material.angular.io/components/datepicker/overview#customizing-the-calen ...

Angular - Automatically update array list once a new object is added

Currently, I'm exploring ways to automatically update the ngFor list when a new object is added to the array. Here's what I have so far: component.html export class HomePage implements OnInit { collections: Collection[]; public show = t ...

Expanding the range of colors in the palette leads to the error message: "Object is possibly 'undefined'. TS2532"

I am currently exploring the possibility of adding new custom colors to material-ui palette (I am aware that version 4.1 will include this feature, but it is a bit far off in the future). As I am relatively new to typescript, I am finding it challenging t ...

Cypress error: Unable to access 'uid' property as it is undefined

Recently in my Cypress project with TypeScript support utilizing the Cucumber Preprocessor, an unexpected exception has started appearing: TypeError: Cannot read properties of undefined (reading 'uid') There are instances where changing to a di ...

How can I achieve this using JavaScript?

I am attempting to create a TypeScript script that will produce the following JavaScript output. This script is intended for a NodeJS server that operates with controllers imported during initialization. (Desired JavaScript output) How can I achieve this? ...

I am experiencing issues with the customsort function when trying to sort a column of

Seeking assistance with customizing the sorting function for a Date column in a primeng table. Currently, the column is displaying data formatted as 'hh:mm a' and not sorting correctly (e.g. sorting as 1am, 1pm, 10am, 10pm instead of in chronolog ...

The authService is facing dependency resolution issues with the jwtService, causing a roadblock in the application's functionality

I'm puzzled by the error message I received: [Nest] 1276 - 25/04/2024 19:39:31 ERROR [ExceptionHandler] Nest can't resolve dependencies of the AuthService (?, JwtService). Please make sure that the argument UsersService at index [0] is availab ...

Oops! The last loader did not provide a Buffer or String as expected

After converting my GraphQL query and HOC component to typescript, I encountered the following error: ERROR in ./client/components/Protected.Route.tsx Module build failed: Error: Final loader (./node_modules/awesome-typescript-loader/dist/entry.js) didn ...

Directive for displaying multiple rows in an Angular table using material design

I am attempting to create a dynamic datatable with expandable rows using mat-table from the material angular 2 framework. Each row has the capability of containing subrows. The data for my rows is structured as an object that may also include other sub-ob ...

Link the chosen selection from a dropdown menu to a TypeScript object in Angular 2

I have a form that allows users to create Todo's. An ITodo object includes the following properties: export interface ITodo { id: number; title: string; priority: ITodoPriority; } export interface ITodoPriority { id: number; name ...