Guide on retrieving the interface property name or key name as a string in Typescript

Currently, I am utilizing the API of Slack and encountering situations where I send JSON requests containing strings that return as property names later on.

I want to create an interface where I can send one of its property names as a string and receive the returning object with correct typing without relying on "magic strings" or constants that need to stay synchronized with the interface.

Here's a quick example:

// Sending out this request to Slack
const request = {
    actionId: "specialProperty"
};

// Later, Slack might return this object
const incomingWebhook = {
    specialProperty: "Value I want to read"
}

I can easily define typing for this using an interface

interface SpecialPropertyInterface {
  specialProperty: string;
}

My concern is that this interface is tied to the string I send out.

Is there a way for me to extract the key/property "specialProperty" from my SpecialPropertyInterface as a string?

Answer №1

I was able to find a solution to my problem using the "keyof" method. Although not perfect, it allowed me to obtain a type-safe string based on an interface property.

Since I had two nested keys, I decided to separate them into two interfaces and utilize keyof to retrieve the string representation of each property.

export interface HoursBlock {
  hours: HoursBlockAction;
}

export interface HoursBlockAction {
  hoursAction: {
    // eslint-disable-next-line camelcase
    selected_option: {
      value: string;
    };
  };
}

...

// The following strings will only be valid if they correspond to the property names.
const hoursBlockId: keyof HoursBlock = "hours";
const hoursActionId: keyof HoursBlockAction = "hoursAction";

// Any deviation from the correct string will result in an error.
// Type '"wrong"' is not assignable to type '"hours"'.ts(2322)
const wrongHoursBlockId: keyof HoursBlock = "wrong";

Answer №2

Let's give this a shot.

To start, append as const to the declaration of your request object:

const request = {
    actionId: "specialProperty"
} as const;

By doing so, the type of the actionId property becomes a literal ("specialProperty") instead of a regular string:

type RequestActionId = typeof request["actionId"] // "specialProperty"

Now, we can utilize it in a mapped index signature:

type SpecialPropertyInterface = {
  [propName in RequestActionId]: string; // specialProperty: string
}

Playground Link

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

Managing a project with multiple tsconfig.json files: Best practices and strategies

I've got a project structured in the following way: \ |- built |- src |- perf |- tsconfig.json |- typings |- tsconfig.json My main tsconfig.json looks like this: "target": "es6", "outDir": "built", "rootDir": "./src", Now, I need to have a ...

An error is anticipated when () is added, but surprisingly, I still encounter an error as well. This issue arises in React-Native and Typescript

I am still relatively new to React-Native, but I have been using React-Native, TypeScript, and integrating it with Firebase. An unusual error has occurred, which is visible in the screenshot below. However, when checking in VSC, the error seems to be non-e ...

Merge the values of an object's key with commas

I'm dealing with an array of objects that looks like this: let modifiers = [ {name: "House Fries", price: "2.00"}, {name: "Baked Potato", price: "2.50"}, {name: "Grits", price: "1.50"}, {name: "Nothing on Side", price: "0.00"} ] My goal is to con ...

What is the best way to extract and display data from an API response object in my

{ "_metadata": { "uid": "someuid" }, "reference": [ { "locale": "en-us", ... bunch of similar key:value "close_icon_size" ...

Troubleshooting Node.js TypeScript breakpoints in Visual Studio Code

I've attempted multiple solutions, but none seem to be working for me. Although the code is running, I'm having trouble setting breakpoints and debugging it. Can you offer any assistance? Below is the configuration script I've tried in VSCo ...

Enhance your Angular material datepicker with additional content such as a close button

I'm currently working on customizing my Angular Material datepicker by adding a button. The goal is to have this button placed in the top right corner and enable it to close the datepicker when clicked. In addition, I also want to include extra conte ...

What is the process for defining the root of a project in ESLint?

I've been working on a project using Next.js and Typescript. My imports look like this: import Component from "/components/Component/Component";, with the root directory being specified as /src. This setup works fine in Next.js, but ESLint k ...

Creating a higher order component (HOC) that utilizes both withRouter and connect functions in React

I am currently working with the following stack: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="87f5e2e6e4f3c7b6b1a9b6b4a9b6">[email protected]</a> <a href="/cdn-cgi/l/email-protection" class="__cf_email__" dat ...

Fixing the forwardRef issue with react-router-dom and material-ui

Despite implementing the forwardRef as recommended in various posts and Material-UI website examples, I am still encountering a warning in the console that has me puzzled. I am working on setting up a drawer with a list of items that are React Router link ...

Visual Studio 2015 does not support compiling typescript files

I'm encountering some difficulties while attempting to set up node with typescript support in Visual Studio 2015 for my web API application. To start fresh, I deleted the node_module folder along with the package.json and tsconfig.json files. Followi ...

Creation of source map for Ionic 2 TypeScript not successful

Struggling with debugging my Ionic 2 application and in need of guidance on how to include souceMap for each typescript file that corresponds to the javascript files. Despite enabling "sourceMap":true in my tsconfig.json file, the dev tools in Chrome do n ...

Make sure to call super.onDestroy() in the child component before overriding it

I find myself with a collection of components that share similar lifecycle logic, so I decided to create a base component that implements the OnDestroy interface. abstract class BaseComponent implements OnDestroy { subscriptions = new Array<Subscript ...

Exploring the realm of Typescript custom decorators: The significance behind context

I'm currently working on a custom decorator that will execute decorated functions based on RxJS events. Everything seems to be going well so far, but I'm facing an issue when the function is executed: the context of the this object is lost. I&a ...

The best location for storing Typescript files within an ASP.NET Core project

My Typescript app is built on AngularJS 2 with ASP.NET Core, and currently I store my TS files in the wwwroot directory. While this setup works well during development, I am concerned about how it will function in production. I aim to deploy only minified ...

Triggering an event through a shared messaging service to update the content of a component

I'm looking for a simple example that will help me understand how I can change the message displayed in my component. I want to trigger a confirmation box with *ngIf and once I confirm the change, I want the original message to be replaced with a new ...

I encountered TS2300 error stating a duplicate identifier appeared once I transferred my code to Angular CLI

Currently undergoing the process of transitioning our code to Angular CLI for our hybrid app. The plan is to migrate the Angular part to CLI while the AngularJS portion continues to be handled by custom Webpack. It's worth noting that both parts (Angu ...

New to React and struggling with updating the DOM

Upon receiving a React project, I am faced with the task of performing a complex state update on my DOM. Here is how my component looks: /** @jsx jsx */ import { jsx } from '@emotion/core'; import { Typography } from '@material-ui/core&ap ...

Utilizing TypeScript: Importing a typed module within a d.ts file (from an npm package)

I am currently working on integrating a definition file into an npm package that has dependencies on React. The specific library in question can be found at https://github.com/eiriklv/react-masonry-component. In my TypeScript project, I have successfully ...

ERROR: The use of @xenova/transformers for importing requires ESM

When working with my Node.js application, I usually start by importing the necessary modules like this: import { AutoModel, AutoTokenizer } from '@xenova/transformers'; Afterwards, I utilize them in my code as shown below: const tokenizer = awai ...

Angular is giving me an undefined Array, even though I clearly defined it beforehand

I've been working on integrating the Google Books API into my project. Initially, I set up the interfaces successfully and then created a method that would return an Array with a list of Books. public getBooks(): Observable<Book[]>{ ...