Why is it not possible to declare an interface or type within a TypeScript class?

I am struggling to define interface | type within a TypeScript class. Here is the code snippet:

class MyClass {
    interface IClass {
        name: string,
        id: string
    }
}

However, I keep encountering this error:

Unexpected token. A constructor, method, accessor, or property was expected.

My Desired Outcome:

I am developing a framework where users can extend the base class Randoms and override certain methods, but the child class does not provide any type intelligence.
Here is an example of the issue in the code:

abstract class RandomsRoute {
   public get (req:Resquest, res:Response): Promise <void> { res.send ('') }
}

// client side

import RandomsRoute, { Request, Response } from '@my-pkg'

class Client extends RandomsRoute {
   // public get (req, res) {res.send('client side')} // error here
   public get (req: Request, res: Response): Promise <void> { res.send ('') }
}

The problematic part seems to be:

{ Request, Response } from '@my-pkg'

I hope to simplify the import process for users and potentially offer better APIs. Any suggestions on how to achieve this?

Answer №1

In the current state, it is not feasible to directly declare types or interfaces within a class body. Although there is a pending feature request for this at microsoft/TypeScript#7061, it has not been integrated into the language yet. Even if implemented, exporting these types out of the class could pose challenges. For instance, while you can define types within functions, those definitions remain hidden outside the function scope:

function foo() {
  interface Foo {
    a: string,
    b: number;
  }
}

const f: Foo = {a: "", b: 1}; // error!
// ----> ~~~ cannot find name Foo

const g: foo.Foo = {a: "", b: 1}; // error!
// ----> ~~~ cannot find namespace foo

function foo() {
  export interface Foo { // error!
  //~~~~ <-- modifiers cannot appear here.
    a: string,
    b: number;
  }
}

Hence, it might not be ideal to define your interface within the class itself.


A recommended alternative, as discussed in this comment on microsoft/TypeScript#7061, is to merge the class with a namespace from which you can subsequently export your type:

export class MyClass {

}
export declare namespace MyClass {
  export interface IClass {
    name: string,
    id: string
  }
}

Then, in another file, you can import MyClass and access both the class and the namespace:

import { MyClass } from '@my-pkg'
const c: MyClass = new MyClass();
const i: MyClass.IClass = { name: "", id: "" };

Playground link to code

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

I'm looking for a way to have an element shift in a particular direction only when two keys are pressed simultaneously

Having trouble moving a square diagonally when two keys are pressed simultaneously. Trying to create an if statement that detects both key presses at the same time and triggers the movement. However, all attempts have failed so far, leaving uncertainty abo ...

html line breaks $.parseJSON

Within my website, I am currently utilizing a TinyMCE window. The method involves PHP fetching an entry from the database, decoding it as JSON, and then having in-page JavaScript parse it. However, issues arise when there are elements like style='colo ...

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 ...

Obtaining a unique diamond pattern overlay on my Google Map

Currently, I am integrating Vue.js with vue-google-maps, and I have noticed a diamond-shaped watermark appearing on the map. After reaching out to Google support, they mentioned that this issue is specific to my tool, indicating it might be related to eith ...

Utilize the Vue-Chartjs plugin registration for a specific chart component only

I am currently working with a chart component in Vue 3 using the composition API. My goal is to incorporate the datalabels plugin into this specific chart only. Upon attempting to register the plugin outside of the chart's data or options, I noticed ...

Guide on sending a JavaScript function to a Pug file using Node.js and Express

In my recent project, I developed a node app using express along with a pug file. The express app is configured to listen on port 3000 and render the pug file. One of the key functionalities involves fetching information from an external API. My goal is to ...

Having trouble getting the form to submit with jQuery's submitHandler

I am in the process of converting a contact form to AJAX so that I can utilize the success function. Currently, I am encountering an issue where the code is halting at the submitHandler section due to it being undefined. Can anyone identify why my submitHa ...

Tips on sending form data, including a file, to Ajax using the onclick() method

My Modal Includes a Form: <div class="modal fade bs-example-modal-lg" id="myMODALTWO" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" id="form-content"> <div class="modal-dialog modal-lg" role="document"> ...

Automate the process of saving information to Google Sheets using Google AppScript

I have a Sheet named 'Automatic' where I've imported a set of data using IMPORTXML. My goal is to update this data list daily at the same time to create a database with various stock quotes over time. Is there a way to accomplish this usin ...

Hidden overflow and identification in URL causes content to be invisible and suddenly appear at the top of the page

I'm encountering a strange issue with containers that have overflow:hidden and when the page URL includes an id. The content gets pushed up and becomes invisible. This problem arises when I apply padding and negative margin at the bottom to create equ ...

I'm looking for assistance on how to execute a render right after making a put or delete request

class ProductApp extends Component { constructor() { super(); this.state = { currentProduct: null, items: [], }; this.handleUpdateSubmit= this.handleUpdateSubmit.bind(this); } componentDidMount() { axios.get('h ...

The characteristics that define an object as a writable stream in nodejs

Lately, I've been delving into the world of express and mongoose with nodejs. Interestingly, I have stumbled upon some functionality that seems to work in unexpected ways. In my exploration, I noticed that when I create an aggregation query in mongoos ...

Determining the type of a keyof T in Typescript

I am currently working on developing a reusable function that takes an observable and applies various operators to return another observable. One issue I am facing is getting the correct type for the value based on the use of the key. The code snippet bel ...

Having difficulty executing the npm test command for my Angular 2 application

I am currently working on an Angular 2 application, and I am fairly new to it. I have set it up with Cordova app and run it through npm. The app starts without any errors and runs smoothly. However, when I try to run the tests using node (i.e., npm test), ...

Making an HTTP request within a forEach function in Angular2

Encountering an issue while using the forEach function with HTTP requests. The _watchlistElements variable contains the following data: [{"xid":"DP_049908","name":"t10"},{"xid":"DP_928829","name":"t13"},{"xid":"DP_588690","name":"t14"},{"xid":"DP_891890" ...

Sending JSON-encoded data using HTML5 Server-Sent Events (SSE) is a

I have a script that triggers an SSE event to fetch json encoded data from online.php. After some research, I discovered methods for sending JSON data via SSE by adding line breaks. My question is how to send JSON through SSE when the JSON array is genera ...

Problem with Next.js router language settings

I have configured different locales for our application including uk and us. For the blog section, we can use either us/blog or just /blog for the uk locale. After switching to the us locale like this: (locale = "us") const updateRoute = (locale ...

Determine the time variance in hours and minutes by utilizing the keyup event in either javascript or jquery

There are 6 input fields, with 5 input boxes designated for time and the result expected to display in the 6th input box. See the HTML below: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input ty ...

Sort through an array using criteria from another array

const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p ...

Retrieving information from Prismic API using React Hooks

I'm having trouble querying data from the Prismic headless CMS API using React Hooks. Even though I know the data is being passed down correctly, the prismic API is returning null when I try to access it with React Hooks. Here is my current component ...