Exploring various options for identifying keys

I have a specific object structure that I receive, and it looks like this:

const object = { a: 10, an: 20 };

This object has predefined keys taken from another source:

const keys = {
    /**
     * A long name that describes what "a" stands for.
     */
    aReallyLongName: "a",

    /**
     * Another long name that describes what "an" stands for.
     */
    anotherReallyLongName: "an"
};

To access the value 10 from object, I use:

object[keys.aReallyLongName] // 10

Is there a way to reference aReallyLongName instead of a in a type-safe manner to retrieve object's a property?


I want to utilize the long names to refer to the short names specifically. For example, referencing a as aReallyLongName rather than a, in a known type-safe manner (even serving as an alias without being part of a keys object).

An ideal scenario would be where object.aReallyLongName compiles to object.a, with the compiler recognizing the expected value as a number.

Possibly something like this:

interface Data {
    /**
     * A long name that describes what "a" stands for.
     */
    "a" as "aReallyLongName": number;

    /**
     * Another long name that describes what "an" stands for.
     */
    "an" as "anotherReallyLongName": number;
}

object.aReallyLongName // compile to: object.a

Use Cases

1. Customizing data obtained from APIs or libraries

API responses can include abbreviated keys or those requiring more descriptive labeling. It would be beneficial to define interface structures that interpret these abbreviations into meaningful terminology.

2. Utilizing shortened MongoDB document keys

In scenarios involving MongoDB storage optimization, using abbreviated keys may prove useful. Describing these keys and their value types while referring to them by more recognizable terms, such as in the context of a project, could enhance efficiency.

Answer №1

To achieve this, you can utilize the keyof operator.

An example implementation would be as follows (I designed keys to be indexable so their properties can have any name, but you can specify them if necessary):

const object = { a: 10, an: 20 };

type Keys = keyof typeof object;

const keys: { [index: string]: Keys } = {
    aReallyLongName: "a",
    anotherReallyLongName: "an"
};

This typing ensures that providing values that are not keys of object will result in a compilation error:

const object = { a: 10, an: 20 };

type Keys = keyof typeof object;

const keys: { [index: string]: Keys } = {
    aReallyLongName: "B",
    anotherReallyLongName: "xn"
};

For further information on this topic, refer to the Advanced Types section of the handbook here.

Alternatively, you could implement a decorator class that defines getters and setters with names different from those of the original object.

The structure of this approach would resemble the following code snippet:

const object: { a: number, an: number } = { a: 10, an: 20 };

class ObjectDescriptor {
    constructor(private original: typeof object) {

    }

    public get AReallyLongName() {
        return this.original.a;
    }

    public set AReallyLongName(value) {
        this.original.a = value;
    }

}

You can then access it like this:

let descriptor = new ObjectDescriptor(object);
descriptor.AReallyLongName;

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

The error message "result.subscribe is not a function" indicates that there was a problem

I encountered an issue with the following error message: Uncaught TypeError: result.subscribe is not a function Here's a screenshot of the error for reference: https://i.sstatic.net/yfhy0.png Despite attempting to handle the error, I'm still s ...

Tips for sidestepping the need for casting the class type of an instance

Looking to develop a function that can accept an argument containing a service name and return an instance of that particular service, all while ensuring proper typing. Casting the instance seems necessary in order to achieve the desired result. To illust ...

tips on waiting for the outcome of an http request (synchronous http request, utilizing http request as a promise)

My TypeScript service loads base data through HTTP requests from a server. The requests are for various data, arranged in order from independent data to data that depends on other data. Due to the asynchronous nature of HTTP requests, there is no guarant ...

Create allowances for specific areas

One of my methods involves the saving of an author using the .findOneAndUpdate function. The structure of AuthorInterface is as follows: export interface AuthorInterface { name: string, bio: string, githubLink: string, ...

Issues with Angular event binding not meeting the expected functionality

I'm currently working on a form that includes fields for usernames and email addresses. Alongside these, I have a separate field where I want the text input by the user to be displayed. I'm facing an issue with event binding within the form – i ...

Should I opt for the spread operator [...] or Array.from in Typescript?

After exploring TypeScript, I encountered an issue while creating a shorthand for querySelectorAll() export function selectAll(DOMElement: string, parent = document): Array<HTMLElement> | null { return [...parent.querySelectorAll(DOMElement)]; } ...

Expanding the functionality of the Typescript number data type

I am trying to enhance the functionality of the number type. Here is the code I attempted: interface NumberExtension { IsInRange(min: number, max: number):boolean; } Number.prototype.IsInRange = function(min: number, max: number): boolean { if (( ...

How to conditionally make a property optional in Typescript depending on the value of another property

I'm a newcomer to Typescript and I've encountered a scenario that has been difficult for me to find a solution for. Any suggestions would be greatly appreciated. My goal is to have the property options be optional when the type is either SHORT_T ...

AngularJS Dilemma: Virtual Machine Data Set but No Rendering in Sight

Below is the AngularJS controller code written in Typescript: /// <reference path='../../definitions.d.ts' /> module baseApp.viewControls.products { export interface IProductsScope extends IAppScope { vm: { product ...

Is it possible to author TypeScript modules in a format other than ES6?

Is it possible to utilize AMD for writing code? define([ 'hb!./some/file.hb' ], function(template) { // }) ...

Is there a way to connect groupby data to an amcharts map?

Currently, I am encountering an issue with binding data to a map. In the past, my data binding process involved using JSON data in records format as shown below: { "latitude":39.7645187, "longitude": -104.9951976, "nam ...

Error Message: Fatal error encountered - TS6046: The value provided for the '--moduleResolution' option is invalid. Valid options include: 'node', 'classic', 'node16', 'nodenext

As I develop a next.js web app with typescript and tailwind CSS, I encountered an issue. When running yarn dev in the terminal, I received this error message: FatalError: error TS6046: Argument for '--moduleResolution' option must be: 'node ...

What is the process for incorporating the QuillJS module into a component in Angular 2?

As a newcomer to Angular 2 and TypeScript, I have been utilizing AngularCLI and NPM to set up my Angular Project. Recently, I installed the Quill node module using NPM for project integration. Now, I am in the process of developing a component where I can ...

Encountering a syntax issue with pipeable operators in Angular Rxjs

I am currently in the process of rewriting this code snippet: Observable .merge(this.searchQuery$, this.lazyQuery$) .do(() => this.loadingPage()) .map(filter => this.buildURL("jaume", Config.security['appName'], filter)) .s ...

What could cause my arguments to "not align with any signature" of console.log?

Here is a basic class example: export class Logger { constructor(private name: string) {} debug(...args: any[]) { console.debug(...args) } log(...args: any[]) { console.log(...args) } } Despite being able to pass anything to console.l ...

The debate between using a Class and an Object Literal comes down to the immut

Is it possible to create read-only properties in object literals? export const Page = { email: 'input[type=email]', password: 'input[type=password]', fillLoginCredentials() { cy.get(this.email).type('email&a ...

"Utilizing the `useState` function within a `Pressable

Experiencing some unusual behavior that I can't quite figure out. I have a basic form with a submit button, and as I type into the input boxes, I can see the state updating correctly. However, when I click the button, it seems to come out as reset. Th ...

What is the best way to incorporate and utilize the JavaScript MediaWiki API in my projects?

I find it frustrating that the documentation for this library is lacking, making it difficult to figure out how to import it into my Typescript/React project. I am attempting to utilize the MediaWiki officially supported library but the examples provided ...

During the present module, retrieve the runtime list of all modules that are directly imported (Javascript/Typescript)

Imagine you have a set of modules imported in the current module: import {A1, A2, A3} from "./ModuleA"; import {B1, B2, B3} from "./ModuleB"; import {C1, C2, C3} from "./ModuleC"; function retrieveListOfImportedModules() { // ...

A guide on retrieving data from Firestore using TypeScript

I've been diving into a chat project using Angular, and Firestore has given me a bit of trouble. Trying to get the hang of typescript while working with it. Within app.module.ts, kicking things off with: import { provideFirebaseApp, getApp, initi ...