Using TypeScript to create a state object in Koa

I am currently utilizing Koa () as the framework for my backend, which consists of Node.js + TypeScript.

Koa permits and recommends using the built-in `ctx.state` to store and pass data between different middleware functions. I have been adhering to this practice and it has been functioning seamlessly.

However, I am facing a challenge in implementing TypeScript with `ctx.state`, as it gets populated at runtime and I am unsure where to begin. I intend to structure `ctx.state`, particularly for the backend response, based on this interface (with various extensions):

export interface ResObj {
  auth: any;
  data: any;
  dataTot?: number;
  error: {
    stack: string;
    code: number;
    message: string;
  };
  extra: any;
  message: string;
  status: number;
  tech: {
    needRefresh: boolean;
  };
}

While one approach could be importing this interface into each endpoint and employing some form of type assertion, that is precisely what I aim to avoid. I have scoured through the Koa documentation and Stack Overflow but have not come across any guidance on this matter.

Answer №1

After reviewing the Koa Type definitions, I was able to find a solution to my problem.

Within the types, they define:

declare namespace Application {
    type DefaultStateExtends = any;
    /** Users can add types to Koa's default state by extending this interface */
    interface DefaultState extends DefaultStateExtends {}
    
    type DefaultContextExtends = {};
    /** Users can add types to Koa's default context by extending this interface */
    interface DefaultContext extends DefaultContextExtends {
      /** Custom properties. */
      [key: string]: any;
    }
}

With this information, it became simple to extend both interfaces (refer to https://www.typescriptlang.org/docs/handbook/declaration-merging.html): within my types, I added

declare module 'koa' {
  interface DefaultState {
    customStateProp: string;
  }

  interface DefaultContext {
    customContextProp: string;
  }
}

Now, everything is properly typed throughout. Keep in mind that you can still create additional properties for both state and context within individual functions or middleware.

I hope this guidance can assist others experiencing the same issue.

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

Tips for eliminating unicode characters from Graphql error messages

In my resolver, I have implemented a try and catch block where the catch section is as follows: catch (err: any) { LOG.error("Failed to get location with ID: " + args.id); LOG.error(err); throw new Error(err); ...

How can you specify the active route in Angular?

I am curious about whether it is possible to set the active route from a script instead of just from the HTML template. Let me provide an example: @Component({ template: `<input type="button" (click)="back()" value="back" ...

Spotlight a newly generated element produced by the*ngFor directive within Angular 2

In my application, I have a collection of words that are displayed or hidden using *ngFor based on their 'hidden' property. You can view the example on Plunker. The issue arises when the word list becomes extensive, making it challenging to ide ...

PhpStorm alerts users to potential issues with Object methods within Vue components when TypeScript is being utilized

When building Vue components with TypeScript (using the lang="ts" attribute in the script tag), there is a warning in PhpStorm (version 2021.2.2) that flags any methods from the native JavaScript Object as "Unresolved function or method". For exa ...

What is the best way to filter an array of objects and store the results in a new variable list using typescript?

On the lookout for male objects in this list. list=[ { id: 1, name: "Sam", sex: "M"}, { id: 2, name: "Jane", sex: "F"}, { id: 3, name: "Mark", sex: "M"}, { id: 4, name: "Mary, sex: "F& ...

When trying to click the button in Navbar.jsx, I encounter an error when attempting to invoke the setShowCart(true) function

I've encountered an issue while trying to call the setShowCart(true) function in Navbar.jsx. I'm unsure of how to fix this. import React from 'react' import Link from 'next/link'; import {AiOutlineShopping} from 'react-ic ...

Guide on accessing device details with Angular2 and Typescript

I'm working on populating a table with details using TypeScript, but I need some assistance. 1. Device Name 2. Device OS 3. Location 4. Browser 5. IsActive I'm looking for a solution to populate these fields from TypeScript. Can anyone lend me ...

The service method call does not occur synchronously

In my OrderServer class, I am utilizing an OrderService to connect to a database and retrieve data every minute. The communication with the web app is handled through SocketIO. Here is a snippet of the code: export class OrderServer { // some required fie ...

Utilize the power of relative import by including the complete filename

When working on my TypeScript project, I have noticed that to import ./foo/index.ts, there are four different ways to do it: import Foo from './foo' // ❌ import Foo from './foo/index' // ❌ import Foo from './foo/i ...

Isolated Modules in Angular Version 17 and Beyond

Having worked with an earlier version of Angular, I am facing issues with my navbar routes not working properly on my Contact Page. Can someone shed some light on this for me? If you want to take a look at the code, here is the link: https://github.com/Lo ...

The Unusual Behavior of Typescript Partial Interfaces

While reviewing the code in a repository I am currently working on, I stumbled upon something that seemed completely incorrect. Here is a snippet of what caught my attention. interface Car { make: string model: string } type SomeType = Partial<Car& ...

Encountered an error of 'npm ERR! invalid semver' when attempting to release an npm package

npm ERR! code EBADSEMVER npm ERR! invalid semver: npm ERR! Check out the full log of this run here: I attempted to reinstall node and semver, but unfortunately it did not resolve the issue. ...

Converting JSON responses from Observables to Arrays of objects in Angular

I have created a custom interface called Table which defines the structure of my data. export interface Table { id: number; title: string; status: string; level: string; description: string; } In my service, I am using HttpClient to se ...

The Ionic project compilation was unsuccessful

Issue: This module is defined using 'export =', and can only be utilized with a default import if the 'allowSyntheticDefaultImports' flag is enabled. Error found in the file: 1 import FormData from "form-data"; ~~~~~~~~ node ...

Using Typescript to test with Karma, we can inject a service for our

I'm currently experiencing a problem with running tests in my application. I recently transitioned to using TypeScript and am still in the learning process. The specific error I'm encountering is: Error: [$injector:unpr] Unknown provider: movie ...

Alert: User is currently engaging in typing activity, utilizing a streamlined RXJS approach

In my current project, I am in the process of adding a feature that shows when a user is typing in a multi-user chat room. Despite my limited understanding of RXJS, I managed to come up with the code snippet below which satisfies the basic requirements for ...

Guide to Integrating Pendo with Angular 8 and Above

I'm having some trouble setting up Pendo in my Angular 8 application. The documentation provided by Pendo doesn't seem to align with the actual scripts given in my control panel. Additionally, the YouTube tutorials are quite outdated, appearing t ...

Compiling Typescript with module imports

In my project, I am working with two files named a.ts and b.ts. The interesting part is that file b exports something for file a to use. While the TypeScript compiler handles this setup perfectly, it fails to generate valid output for a browser environment ...

Is the type narrowed by type guards only when true is returned?

It was my understanding that a type guard handling multiple types instanceOfA(arg: A | B | C): arg is A, would narrow the type to either A (if the guard returns true) or B | C (if it returns false) However, in the case of instanceOfB below, when returning ...

Angular Build Showing Error with Visual Studio Code 'experimentalDecorators' Configuration

Currently experiencing an issue in VSC where all my typescript classes are triggering intellisense and showing a warning that says: "[ts] Experimental support for is a feature that is subject to change in a future build. Set the 'experimentalDeco ...