Utilize the class designation to label interface attributes

Here is a link to a great TypeScript Playground that demonstrates what I am trying to accomplish: TS Playground.

The goal is to use the variable Class.name to name the properties in my code.

class MyClass {
  readonly a: {b: number} = { b: 123 };

  constructor() {
    this.a.b = 1;
  }
}

// try1
interface Actions {
  [MyClass.name + '_action1']: string,
  [MyClass.name + '_action2']: number
}

interface Actions2 {
  MyClass_action1: string,
  MyClass_action2: number
}

// expect a and b to behave the same
const a: Actions2 = {
  MyClass_action1: '4',
  MyClass_action2: 1
}

const b: Actions = {
  MyClass_action1: '4',
  MyClass_action2: 1
}

Do you think this is achievable?

Answer №1

Finding a straightforward solution to this issue is challenging.

The name attribute of class constructors is classified as a string, consistent with the inherited properties from the Function interface. The compiler struggles with acknowledging the string literal type associated with the name. Refer to microsoft/TypeScript#43325 and its related concerns for more information.

Even if we can guarantee that during runtime, a class Foo {⋯} will have Foo.name === "Foo" (assuming we don't encounter peculiar scenarios where it gets overwritten by a static property or subject to minification or obfuscation), TypeScript still faces challenges in assigning the type "Foo" to Foo.name. This complexity arises due to the hierarchical nature of the static side of a class, wherein, if Bar extends Foo {⋯} exists, TypeScript anticipates Bar.name to align with Foo.name. Consequently, if Foo.name is designated as "Foo", then Bar.name must also correspond to "Foo". Realistically, this alignment rarely holds true during runtime. To navigate through these complications, TypeScript often avoids stringent types, leading to somewhat diluted specifics compared to users' preferences.

A hypothetical prospect involves the introduction of a nameof operator in JavaScript akin to C#'s functionality, which could prompt TypeScript to extend support accordingly (refer to microsoft/TypeScript#1579). By waiting for such developments, one might anticipate an official method within TypeScript allowing extraction of class names within the type system.

Unless these anticipated changes materialize, users are reliant on manual specification. A viable approach entails consolidating relevant details manually, as illustrated below:

declare namespace MyClass {
  export const name: "MyClass"
}

Subsequently, users may define their keys leveraging template literal types (providing the sole avenue for string concatenation at the type level):

const action1 = `${MyClass.name}_action1` as const;
const action2 = `${MyClass.name}_action2` as const;
interface Actions {
  [action1]: string,
  [action2]: number
}

This technique might partially address user requirements; however, until further advancements transpire, users face two options—implement similar strategies illustrated above or concede defeat.

Explore the code on Playground

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

What could be causing Store.getState() to return an 'any' type following the implementation of rootReducer with combinedReducers?

Seeking assistance with utilizing a root reducer to encapsulate my combined reducers for the purpose of resetting them upon a reset store action. However, I am facing an issue where I cannot directly access the reducers using Store.getState().recuder1 ...

Error in Angular: Trying to access the property 'id' of an undefined value

I am facing an issue with a div tag in my HTML file. The code snippet looks like this: <div *ngIf="chat.asReceiver.id != user?.id; else otherParty"> Unfortunately, it always returns the following error: ERROR TypeError: Cannot read propert ...

Angular6 returns the result after subscribing to an HTTP POST request

Currently, I am in the process of learning angular and attempting to create a component that allows users to register through my web API. Within my component, the code on form submission looks like this: onSubmit(contactFormRef: NgForm) { const resu ...

What is the capability of dynamically generating an index in Typescript?

Can you explain why the Typescript compiler successfully compiles this code snippet? type O = { name: string city: string } function returnString(s: string) { return s } let o1: O = { name: "Marc", city: "Paris", [returnString("random")]: ...

I am currently working on implementing data filtering in my project. The data is being passed from a child component to a parent component as checkboxes. Can anyone guide me on how to achieve this filtering process

Below is the code I have written to filter data based on priorities (low, medium, high). The variable priorityArr is used to store the filtered data obtained from "this.data". The following code snippet is from the parent component, where "prio" is the v ...

Using jQuery to bind data to Angular's *ngFor directive

I am currently in the process of customizing a horizontal timeline resembling https://codepen.io/ritz078/pen/LGRWjE/. The demo includes hardcoded dates which I want to replace with an array of Dates (timelineParsedDates) <ol> <li><a href ...

Challenges with invoking functions within ngFor loop during unit testing in Angular 12

I am currently learning about unit testing and I am facing an issue with calling a function inside an *ngFor loop in an Angular 12 application. I have an observable that contains an array of objects and it is working correctly, iterating through the data p ...

Tips for relocating the indicators of a react-material-ui-carousel

I am working with a carousel and dots indicators, but I want to move the indicators from the bottom to the circular position as shown in the image below. I attempted using a negative margin-top, but the indicators ended up being hidden. Is there another ...

Passing props dynamically with TypeScript ENUMs

As I begin learning TypeScript with React, I am creating practice scenarios to enhance my understanding along the way. export enum Colors { Blue = "#0000FF", Red= "#FF0000", Green = "#00FF00", } export const ColorComponent: React.FC<props> = ...

Tips for including or excluding a bootstrap "active" class within an Angular 4, Typescript 2 environment

Struggling to integrate my Bootstrap Framework with Angular 4 - Typescript, I am facing difficulty in getting my Tabbed Registration Form to function correctly. In Bootstrap, this is the JS file that manages the addition and removal of the active class up ...

The type of the element is implicitly set to 'any' because the expression 'keyof IMyObj' cannot be used to index the type

Trying to avoid specifying types in TypeScript and setting a value by accessing its key is causing a TypeScript error. Despite looking at multiple StackOverflow posts, I couldn't find a solution. I encountered a similar issue with my code and tried r ...

(NG2-CHARTS) Unable to connect to the Chart Type as it is not recognized as a valid property for binding

I encountered an issue with my Chart Component where I am seeing the error message below. I have successfully imported ChartsModule into my app.module.ts file, but I am unsure why this error is occurring? Can't bind to 'ChartType' since ...

Encountering a deadly mistake with LNK1181 while attempting to npm install web3

On my Windows system, I attempted to install the web3 node package using npm install. I followed the necessary steps by first installing Windows build tools: npm install --global --production windows-build-tools This command executed without issues, but ...

Caution: Updating a component is not possible during the rendering of another component. ReactJS

I am encountering an error in my ReactHooks/Typescript application with a Navigation component that renders a PatientInfo component. The PatientInfo component is conditionally rendered based on the props it receives, determined by a searchbox in another ch ...

ParcelJS takes a unique approach by not bundling imported JavaScript libraries

My NodeJS app, which is a Cloudflare Worker, seems to be having trouble with bundling the 'ping-monitor' dependency. In my main typescript file (index.ts), I import the handler module and the first line reads: const Monitor = import('ping-m ...

Jest doesn't seem to be triggering fs.createReadStream as expected

I've been using fs.createReadStream to read files and have encountered a strange issue. When I run the function from the file itself, it works perfectly fine and triggers the events (data, end). However, when I attempt to call the function in order to ...

An exception is thrown by TypeScript's readline.createInterface function

My current project involves creating an electron app. I am facing an issue in the main.ts file where I have constructed a seemingly simple class with a constructor that is not running as expected. The problem arises when the call to readline.createInterfac ...

`Evaluating a TypeScript React component using Mocha: A thorough examination of TSX components with TypeScript

Following the transition of my React project to TypeScript and Babel7, I encountered an issue with a component named abc.tsx (previously abc.js). While the component compiles successfully on npm start and loads in the browser without any issues, running th ...

TS: How can we determine the type of the returned object based on the argument property?

Assume we have the following data types type ALL = 'AA' | 'BB' | 'CC'; type AA = { a: number; }; type BB = { b: string; }; type CC = { c: boolean; }; type MyArg = { type: ALL }; I attempted to create a mapping between type n ...

Ways to enable or disable async functions in the Facebook web SDK

Lately, I made a change in my app to transition from compiling async functions to simply using the regular async syntax. However, I've encountered an issue where I'm receiving an error message Expression is of type asyncfunction, not function fro ...