What exactly is a more defined type of interface in Typescript?

Dealing with a type in typescript that consists of an object where all properties must be of type number. I am trying to create more concrete interfaces based on this type and pass them as generic parameters to a class that extends my basic type. However, I keep running into the same TypeScript error:

Index signature for type 'xxx' is missing in type 'yyy'

I wonder if there's a way to accomplish what I'm trying to do in TypeScript. The closest solution I found was extending the moreConcrete interface from the basic type, which eliminates the error but causes me to lose autocompletion and other intellisense features when using the interface.

You can view an example in this fiddle: Fiddle

Below is the code in the fiddle:

type basic = {
    [key: string]: number
}

class A<TInput extends basic> {

}

interface moreConcrete {
    a: number,
    b: number
}
const test = new A<moreConcrete>(); // this does not work like this

interface otherMoreConcrete extends basic {
    a: number,
    b: number
}
const test2 = new A<otherMoreConcrete>(); // this does not give any errors
const typeTest: keyof otherMoreConcrete = 'as'; // this accepts as as a key of otherMoreConcrete, because of the extension to `basic`, this should be an error

Answer №1

If you want a deeper insight into this issue, check out this response.

Summary:

interfaces don't come with default indexing, while types do. To resolve an error, simply switch from using interface to type. So instead of:

interface moreConcrete {
    a: number,
    b: number
}

do:

type moreConcrete= {
    a: number,
    b: number
}
const test = new A<moreConcrete>(); // works fine

For additional examples, refer to my write-up.

Is it absolutely safe to use type over interface? Not necessarily. It hinges on your code and objectives. I can't account for every scenario, so thorough testing is advised.

Opting for type over interface may be advisable in this instance due to the indexed type expectation in the A class.

Regarding the second issue:

interface otherMoreConcrete extends basic {
    a: number,
    b: number
}

const test2 = new A<otherMoreConcrete>(); // no errors occur here
const typeTest: keyof otherMoreConcrete = 'as'; // accepts 'as' as a key even though it should throw an error due to extension to `basic`

The absence of an error is because there's a notable distinction between otherMoreConcrete interface and moreConcrete. otherMoreConcrete extends basic, indicating it possesses indexed properties besides a and b.


type otherMoreConcrete = {
    [x: string]: string;
    a: "a";
    b: "b";
}

So, if you wish to trigger an error in the final example, go with type instead of interface:

type basic = {
    [key: string]: number
}

class A<TInput extends basic> {}


type moreConcrete = {
    a: number,
    b: number
}
const test = new A<moreConcrete>(); // works fine

type otherMoreConcrete = {
    a: number,
    b: number
}


const test2 = new A<otherMoreConcrete>(); // works fine
const typeTest: keyof otherMoreConcrete = 'as'; // triggers an error

Interactive tool

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

"Is there a way to generate a Date Object without including the time component while utilizing the format YYYY-MM-DD within

I'm struggling to generate a Date object with just the date when using 'YYYY-MM-DD' input format. Here's the code I'm using: let date1 = new Date('2022-01-06') let date2 = new Date('01/06/2022') The results ar ...

Developing a unique TypeScript singleton pattern tailored for multiple PouchDB instances

I have developed a node application that interfaces with multiple databases. I've designed a class which allows me to create various databases effortlessly, as they share similar CRUD operations. The Class: class DatabaseService { private dbName: ...

Tips for capturing an event from a bespoke button component integrated within an ng2-smart-table

Currently, my task involves triggering an event in Angular2 by clicking a button within a child component that is displayed within a ng2-smart-table located in the parent component as a column. Unfortunately, I am facing the challenge that I cannot add a ...

Send a function as a property to a child functional component

I am attempting to pass a callback function to a functional component child in order to update the parent. However, I am encountering an error Uncaught TypeError: updateVal is not a function within the child component (I will add a comment to indicate wh ...

Encountering an error with dynamic routing in Angular 4 when using dynamic components

Upon receiving routing configuration from a server and loading it before the application bootstrap, the config.json file contains the following setup: [{ "path": "dashboard", "component": "SingleComponent", "data": {...} }, { "path": "payment", ...

How to modify the background color within the mat-menu-panel

Incorporating angular 9 and less into my current project, I have encountered an issue with a mat-menu-panel where my mat-menu-item is located. While I have successfully changed the color of my mat-menu-item, I am now faced with the challenge of changing th ...

Tips for retrieving modified data from a smart table in Angular 4

Currently, I am working on an angular project where I am utilizing smart table. Here is a snippet of my .html file: <ng2-smart-table [settings]="settings" [source]="source" (editConfirm)="onSaveConfirm($event)" (deleteConfirm)="onDeleteConfirm($event ...

What is the method for extracting date of birth data from .NET to Angular?

Struggling to fetch the date of birth from the database where it has been stored. After searching through multiple resources online, I am still unsure about how to accomplish this task. export class DetailsEmployeeComponent implements OnInit{ employeeD ...

Tips for linking the controls of storybook with manual state updates

I'm a newcomer to storybook and frontend development. Below is the code for my checkbox.tsx component: import React from 'react'; import styles from './checkbox.module.css'; // Make sure this import is correct interface CheckboxP ...

Unexpected outcome in Typescript declaration file

This code snippet is dealing with the 'legend' function: legend = (value) => { return typeof value === 'boolean' ? { 'options.legend.display': value } : { 'options.l ...

Make sure that spyOnProperty is used to create configurable properties using Object.defineProperty

After upgrading to Angular 9 (from 8.1) and Typescript 3.7 (from <3.6), I've come across an issue with the spyOnProperty method. This is how my service looks: class Backend { public get baseURL(): string { return 'http://baseurl.com/&a ...

Managing DOM elements within a Vue 3 template using Typescript

As I delve into the world of Vue 3 as a beginner, I encountered a challenge when it came to managing the DOM within Vue 3 templates. Let's take a look at the source code. MainContainer.vue <template> <div class="main-container" r ...

Search timeout restriction

I have a function that makes a request to the server to retrieve data. Here is the code for it: export default class StatusChecker { constructor() { if (gon.search && gon.search.searched) { this.final_load(); } else { this.make_req ...

The confusion arises from the ambiguity between the name of the module and the name of

In my current scenario, I am faced with the following issue : module SomeName { class SomeName { } var namespace = SomeName; } The problem is that when referencing SomeName, it is pointing to the class instead of the module. I have a requireme ...

This TypeScript error occurs when the props are not compatible and cannot be assigned to

Hello fellow Internet dwellers! I am a novice in the world of coding and TypeScript, seeking some assistance here. I am attempting to extract an array of objects from props, transform it into a new object with specific information, and then return it - ho ...

Transform JSON into an Array and generate a new Array from a collection of Arrays

I'm struggling with generating a table in Angular2 from JSON data because I need to pivot the information, but my usual method doesn't seem to work for this scenario. Below is an excerpt of the JSON data I am working with: [ { "ValueDate" ...

What is the best way to send various parameters to a component using [routerLink] or router.navigate?

My app-routing.module.ts is configured as shown below: const routes: Routes = [ { path: "branches/:branch", component: BranchesComponent }, // ... ]; In addition, in my app.component.html, I have the following code: <li> ...

Dynamic import of a SASS file in VueJS using a variable such as process.env

Is there a way to dynamically import a file using environment variables? I want to include a specific client's general theme SCSS to my app.vue (or main.ts) I'm thinking of something along the lines of: <style lang="sass"> @import"./th ...

Limiting the number of characters in a textarea using React with TypeScript

Having encountered two issues, I've developed a textarea component that not only allows users to input text but also keeps track of the number of characters they have typed. First Issue: I'm attempting to check if the length of the current input ...

What is the best way to reload a React/TypeScript page after submitting a POST request?

I am working on a custom plugin for Backstage that interacts with Argo CD via API calls. To retrieve application information, I make a GET request to the following endpoint: https://argocd.acme.com/api/v1/applications/${app-name} If the synchronizati ...