Retrieving the attribute key from a dynamically typed object

Having this specific interface structure:

interface test {
   [key: string]: string
}

along with an object defined as follows:

const obj: test ={
   name: 'mda',
   telephone: '1234'
}

Attempting to utilize this object in a variable, the intellisense feature fails to function properly for this particular object. Essentially, it allows selecting a key that does not actually exist within the object.

const myName = obj.ndfnasdfn

No error is displayed by the compiler for such a key selection. You can access the playground area here: playground

An update involving a nested object: For this nested object scenario, what are the possible solutions? I implemented @Titian Cernicova-Dragomir's solution for the nested object mentioned below, however, no error is shown by the compiler.

interface test {
[key: string]: string
 }

 function createTest<T extends test>(o: T) {
     return o;
 }
 interface state {
     test1: test,
     test2:test
 }
 const state: state = {
    test1:createTest({
        t1:'m',
        t2:'e'
  }),
  test2: createTest({
    t3:'sss'
     })
  }
 const {test1, test2} = state
 const t1 = test1.sdfsafsdf //no error

playground

Further update: If we choose not to utilize the createTest function, and instead don't specify the type for the state object like demonstrated here playground

I proposed using types for the state object to prompt a compiler error for keys that do not exist in test1

Answer №1

When you explicitly specify the type of a variable, it becomes the final type and the compiler does not infer any additional information for that variable.

If you remove the annotation, the compiler will infer the type of the variable.

const obj ={
   name: 'mda',
   telephone: '1234'
}

If you want to restrict a variable to only accept string values, you can achieve this by using a function to constrain the type while still letting the compiler infer the overall type:

interface test {
    [key: string]: string
}

function createTest<T extends test>(o: T) {
    return o;
}

const obj = createTest({
    name: 'mda',
    telephone: '1234'
    // age: 10 // This will cause an error as age is not a string
});
obj.name // Ok
obj.sss // Error

Playground link

For nesting data structures, such as in the example provided, you need to create a function to generate state instead of just test. The same rule applies - when the types of test1 and test2 are explicitly defined, those types become final regardless of what createTest returns.

interface test {
    [key: string]: string
}

interface state {
    test1: test,
    test2:test
}
function createTest<T extends state>(o: T) {
    return o;
}
const state = createTest({
    test1: {
        t1: 'm',
        t2: 'e'
    },
    test2: {
        t3: 'sss'
    }
});
const {test1, test2} = state
const t1 = test1.sdfsafsdf //This will result in an error

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

We were unable to locate a declaration file for the module known as 'firebase-tools'

As I delve into writing my inaugural cloud function for Firebase, I find myself in need of the firebase-tools module. To bring it on board, I updated my dependencies by editing the package.json file and executing the command npm install. Next, I attempted ...

What is the best way to pass props to a styled component (e.g., Button) in Material-UI

One of my tasks involves creating a customized button by utilizing the Button component with styled components. export const CustomButton = styled(Button)({ borderRadius: "17px", fontWeight: 300, fontSize: ".8125rem", height: &q ...

Sending real-time data from the tRPC stream API in OpenAI to the React client

I have been exploring ways to integrate the openai-node package into my Next.js application. Due to the lengthy generation times of OpenAI completions, I am interested in utilizing streaming, which is typically not supported within the package (refer to he ...

Custom Email Template for Inviting Msgraph Users

I'm currently exploring the possibility of creating an email template for the MS Graph API. I am inviting users to join my Azure platform, but the default email they receive is not very visually appealing. public async sendUserInvite(body: {email: < ...

Updating a label dynamically in Angular

QUESTION: Is there a way to dynamically change the text of a label based on a certain condition? Specifically, I want the label to be blank when I'm on a specific route in my App. CURRENT APPROACH: <RadSideDrawer allowEdgeSwipe=&quo ...

Step-by-step guide to start an AngularJs application using TypeScript

I have developed an AngularJS App using TypeScript The main app where I initialize the App: module MainApp { export class App { public static Module : ng.IModule = angular.module("mainApp", []) } } And my controller: module MainApp { exp ...

Ways to utilize a field from an interface as a type of index

interface Mapping { "alpha": (a: string) => void "beta": (b: number) => void } interface In<T extends keyof Mapping> { readonly type: T, method: Mapping[T] } const inHandlers: In<"alpha"> = { type ...

Is there a way to determine the specific type of a property or field during runtime in TypeScript?

Is there a way to retrieve the class or class name of a property in TypeScript, specifically from a property decorator when the property does not have a set value? Let's consider an example: class Example { abc: ABC } How can I access the class or ...

Sorting the material table based on the column IDs, which usually correspond to the column names, may not align with the properties of the data

.ts this.displayedColumns = [ { key: 'id', header: '#' }, { key: 'fullname', header: 'Full name' }, { key: 'email', header: 'email' }, { key: 'roleName', header: ...

I have successfully implemented useLazyQuery in a functional component, but now I am looking to integrate it into a class component. Can you provide guidance on how to achieve

Recently, I encountered an issue with my functional component that contains 3 checkboxes and 1 button. I utilized the useLazyQuery hook to ensure that my query was only sent upon clicking the button. However, a major drawback is that my component re-rend ...

Encountering an Issue with Dynamic Imports in Cypress Tests Using Typescript: Error Loading Chunk 1

I've been experimenting with dynamic imports in my Cypress tests, for example using inputModule = await import('../../__tests__/testCases/baseInput'); However, I encountered an issue with the following error message: ChunkLoadError: Loading ...

Typescript loading icon directive

Seeking to create an AngularJS directive in TypeScript that wraps each $http get request with a boolean parameter "isShow" to monitor the request status and dynamically show/hide the HTML element depending on it (without utilizing $scope or $watch). Any ...

What is the reason for TypeScript not displaying a type mismatch error in this particular instance?

After starting to use React with TypeScript, I defined my types as follows: type CardInfo = { cardIndex: null | number; title: string; note: string; _id: string; from: string; cardId: string; }; type ContentType = { title: string; note: st ...

Creating nested Angular form groups is essential for organizing form fields in a hierarchical structure that reflects

Imagine having the following structure for a formGroup: userGroup = { name, surname, address: { firstLine, secondLine } } This leads to creating HTML code similar to this: <form [formGroup]="userGroup"> <input formCon ...

Adding Profile Photos to Authenticated User Accounts in Firebase / Ionic: A Step-By-Step Guide

I have thoroughly gone through the Firebase Docs on "Managing Users" for web along with watching their instructional video on YouTube. Despite following the code they provide, I am encountering an error message that states: "Property 'afAuth' do ...

Receiving an error when attempting to inject the Router in a component constructor without using the elvis operator

Upon launching my app, I desire the route /home to be automatically displayed. Unfortunately, the Angular 2 version I am utilizing does not support the "useAsDefault: true" property in route definitions. To address this issue, I considered implementing th ...

Typescript: create a type similar to keyof but with a particular value type

I have an interface called MyInterface interface MyInterface { field1: boolean, field2: MyType, field3: MyType } In this interface, I want to create a new type that contains only the keys which have values of type MyType. While I know about the key ...

Populating datasets with relative indexing

I am working on a code where I need to fill the datasets with the property isProjected set to 1. There are 3 datasets - lower estimate, projected, and upper estimate. The goal is to fill the Lower Estimate and Upper Estimate with a background color of rgba ...

A guide on implementing TypeScript with React Native's platform-specific extensions

The issue at hand: In my react native project, I am using a custom hook that has platform-specific code. I need to import this hook based on the platform in use. When I import it as import useWifi from 'hooks/use-wifi.android';, everything works ...

I encountered a SyntaxError while parsing JSON due to an absence of a number after a minus sign at position 1

I am trying to use the replicate model visoar/product-photo:edf42659dae0da88a26dba4912e7e4bb6c2fba25b1e1c6a5464cf220e467bce0, but when I provide it with an image and a prompt like on this page.tsx: "use client" import { LandingNavBar } from &apo ...