Extending an interface in TypeScript does not permit the overriding of properties

While working with Typescript, I encountered an issue where I couldn't make a property not required when overwriting it. I have defined two interfaces:

interface IField {

  label:                string;
  model:                string;
  placeholder?:         string;
  addon?:               string;
  showOn?:              IDictionary <string | number>;
  maxlength?:           number;

}
interface ICheckboxField extends IField {

  model?:               string;
  type:                 'checkbox';
  default?:             string;
  options:              IOption[];
  validation?:    {
    required?:          string;
  };
}

In the ICheckboxField interface, I tried to set the model property as not required. However, all other fields that extend from IField require a mandatory model.

I am curious if this limitation is inherent to Typescript or if there is a workaround besides avoiding extending the interface and manually adding specific properties for each interface?

Answer №1

To consolidate the shared properties of IField and ICheckboxField into a common interface, you can create an interface like this:

interface IBase {
    label: string;
    placeholder?: string;
    addon?: string;
    showOn?: IDictionary;
    maxlength?: number;
}

interface IField extends IBase {
    model: string;
}

interface ICheckboxField extends IBase {
    model?: string;
    type: 'checkbox';
    default?: string;
    options: IOption[];
    validation?: {
        required?: string;
    };
}

Alternatively, you could split the IField interface into two separate interfaces:

interface IField {
    label: string;
    placeholder?: string;
    addon?: string;
    showOn?: IDictionary;
    maxlength?: number;
}

interface IFieldOptionalModel extends IField {
    model?: string;
}

interface IFieldMandatoryModel extends IField {
    model: string;
}

interface ICheckboxField extends IFieldOptionalModel {
    type: 'checkbox';
    default?: string;
    options: IOption[];
    validation?: {
        required?: string;
    };
}

Answer №2

Attempting to replace a strict type (IField) with a less strict type (ICheckboxField) where a mandatory property is required is not allowed.

The compiler does not approve of this, but the reverse scenario is acceptable:

interface Loose {
  label:string;
  model?:string;
}

interface Strict extends Loose {
  model:string;
}

var a:Loose = {
  label:"bar",
}

var b:Strict = {
  label: "baz",
  model: "me"
}

To work around this, you can create another interface that includes both, where the model field is initially optional and then enforced as mandatory in IField.

An alternate approach could involve using keyof and the Lookup Types introduced in TypeScript 2.1

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 message "Undefined is not a constructor" can occur when using Ionic2 with Karma and Jasmine

I'm facing a challenge while trying to create tests for an Ionic2 App using Karma + Jasmine. I encountered a runtime error and, given my lack of experience, I'm having trouble pinpointing the actual issue. Here is my setup: test.ts This file con ...

Working with TypeORM to establish two foreign keys pointing to a single primary key in a table

For my project, I am looking to establish bi-directional ManyToOne - OneToMany relationships with two foreign keys that reference the same primary key. Specifically, I have a 'match' table that includes two players from the 'player' tab ...

Tips for leveraging angular CLI's async import feature with webpack

I've been attempting to utilize webpack's (2.2.1) async module loading as outlined in the documentation. In addition, I have explored various examples for reference. However, I keep encountering the error message Declaration or statement expecte ...

Issues with Cross-Origin Resource Sharing (CORS) have been identified on the latest versions of Android in Ionic Cordova. However, this problem does not

I am encountering an issue with my TypeScript Ionic code. It works well in browsers and some older mobile devices, but it fails to function on newer Android versions like 8+. I need assistance in resolving this problem. import { Injectable } from '@an ...

Enhance the express Response type and then export my updated type as a distinct module

I am currently working on developing a new 'common' module for my team. One of the key features it should have is an extension of both the response and request objects in Express. Our main goal is to achieve two things - first, extending the Req ...

What is the proper way to enhance properties?

In the process of developing a Vue3 app using Typescript, one of the components is designed to receive data through props. Initially, everything functioned smoothly with the basic setup: props: { when: String, data: Object }, However, I de ...

Can you explain the distinction between using get() and valueChanges() in an Angular Firestore query?

Can someone help clarify the distinction between get() and valueChanges() when executing a query in Angular Firestore? Are there specific advantages or disadvantages to consider, such as differences in reads or costs? ...

Error: TypeScript is unable to locate the 'moment' module

My TypeScript React application was set up using npx create-react-app --template typescript. However, when I try to start the app with npm start, I encounter an error in one of my files: TypeScript error in /<path>/App.tsx: Cannot find module ' ...

Sending the chosen dropdown ID to a different component

In my application, there is a component named list where I am showcasing all the names of my customers in a dropdown, as illustrated below: When a particular item (i.e., customer) is selected from the dropdown, I would like to emit that id to a method/fun ...

Struggling with TypeScript compilation in a Vue.js project? Encounter error code TS2352

Here is my code snippet from window.ts import Vue from 'vue' interface BrowserWindow extends Window { app: Vue } const browserWindow = window as BrowserWindow export default browserWindow Encountering a compilation error Error message: TS2 ...

Issue TS2315: Type 'ElementRef' does not support generics

While attempting to integrate @angular/materials into my application, I encountered a successful compilation with the following error messages: webpack: Compiled successfully. ERROR in node_modules/@angular/material/button-toggle/typings/button-toggle.d.t ...

Experiencing a typeerror with the Event attribute

I encountered an issue while trying to target an event. Here is what I attempted: public gotoPage(event: Event): void { const gettest = (event.target as HTMLElement)?.getAttribute('href'); if (href) { const testModule = "valu ...

Issue with ngFor displaying only the second item in the array

There are supposed to be two editable input fields for each section, with corresponding data. However, only the second JSON from the sample is being displayed in both sections. The JSON in the TypeScript file appears as follows: this.sample = [ { "se ...

Updating state in React without providing a key prop is a common issue, especially when

Currently, I am working on implementing a Radio Group where I want the radio button's checked value to update when another button is clicked. In the example provided below, it seems that the desired effect can only be achieved using the "key" prop. Is ...

Leverage the power of mathematical functions within Angular to convert numbers into integers

In my Angular 7 Typescript class, I have the following setup: export class Paging { itemCount: number; pageCount: number; pageNumber: number; pageSize: number; constructor(pageNumber: number, pageSize: number, itemCount: number) { thi ...

What is the best way to prevent the hassle of manually reloading a VS Code extension each time I make updates

While working on my VS Code extension, I keep encountering the issue of opening a new instance of VS Code every time I run the extension to view recent changes. This becomes especially tedious when using VS Code remote and having to enter my password twice ...

TypeScript error: Cannot find property 'propertyName' in the 'Function' type

I encountered an issue with the TypeScript compiler when running the following code snippet. Interestingly, the generated JavaScript on https://www.typescriptlang.org/play/ produces the desired output without any errors. The specific error message I recei ...

Setting Angular FormControl value to null within a service

My Angular form is reactive and collects mobile numbers along with other details. Here is the code snippet: component.html <form [formGroup]="contactDetailsForm"> <ngx-intl-tel-input [cssClass]="'ngxIntlInputBorder'&quo ...

Do you think this is a clever way to circumvent using ENUM for a parameter?

As I continue to explore different coding styles in Typescript and Angular, I recently encountered a method without any comments attached to it. It seems like this method is enforcing that the value passed in must be one of the defined options, but strang ...

What is the proper way to write a function that verifies the presence of a key in an object and then retrieves the associated value?

After holding out for a while hoping to stumble upon the solution, I've decided to give it a shot here on SO since I haven't found it yet. import { PDFViewer, MSViewer } from './viewerclasses' //attempting to incorporate a union of key ...