Having T extend Record<string, any>, the keyof T does not return 'string' as a type

My goal is to achieve the following:

type UserDataProps<FieldName extends keyof DataShape, DataShape extends Record<string, any>> = {
  id: string;
  value: DataShape[FieldName];
}

const userDataBuilder = <FieldName extends keyof DataShape, DataShape extends Record<string, any>>(
  name: FieldName,
  data: DataShape,
): UserDataProps<FieldName, DataShape> => {
  return {
    id: name,
    value: data[name],
  }
}

However, I encounter an error indicating that 'name' is of type string | number | symbol.

This seems odd since DataShape does extend Record<string, any>, meaning its keys should be strings.

Is this behavior expected? If so, is there a way to resolve it?

Thank you :)

Playground link: https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiBiB7ATgWwArMWAzgHngEsIAbAEwDkBDVaCAD2AgDsycoBrCERAMyiRoAygAsqkADQCUqUeLqMWbKACUIAYxRk8OYMkLMA5lKrMQAPnNQAvFADeAKChRCZAFxRd+owG4nUADcqEgBXCA9BWTFIAG0iUkoaCABdPwBfBwdNZl0oXhlMbBwAIRDCcghkGygCYnJqWigGJlZ2Lh5+SLlJaWFohRblNU1kbS8DYyhTC3MACn9mJIi6xNoJf3y0CJluiHWASg84SMLcWoSGvd6o+StrK0dnZAhgEORme39nVw9Fta-AsEwh5NqgYn8UutnBk0kA

Answer №1

There are 3 types of index type which are string, number, and symbol. Therefore, in order to assign to it, the id must have one of the same types mentioned above.

type MyFormProps = {
  id: string | number | symbol;
}

Alternatively, you can cast your type as a string if you believe the input is always a string:

const formPropsBuilder = <K extends keyof T, T extends Record<string, any>>(name: K): MyFormProps => {
  return {
    id: name as string,    
  }
}
``

Answer №2

It struck me as odd too. Here's how I approached it:

type KeyOfTypeRecord<T extends Record<string, any>> = keyof T extends string
  ? keyof T
  : never

With this, you'll find that

KeyOfTypeRecord<Record<string, any>>
now extends a string.

Answer №3

Is there any specific reason for including the extra generic type? In my opinion, it can be simplified as follows:

type FormProps = {
  id: string;
}

const buildFormProps = <FieldName extends keyof Record<string, any>>(name: FieldName): FormProps => {
  return {
    id: name,
  }
}

By making this adjustment, the error is resolved.

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 effectively managing loading and partial states during the execution of a GraphQL query with ApolloClient

I am currently developing a backend application that collects data from GraphQL endpoints using ApolloClient: const client = new ApolloClient({ uri: uri, link: new HttpLink({ uri: uri, fetch }), cache: new InMemoryCache({ addTypename: f ...

Experiencing an issue when attempting to deploy Strapi CMS with TypeScript on Railway - encountering the error message: "Unable to locate module 'typescript'"

Issue with Deploying Strapi CMS in TypeScript to Railway Currently facing challenges while trying to deploy Strapi CMS written in TypeScript to Railway. Despite the availability of a JavaScript template, there's a lack of a specific TypeScript templa ...

Dealing with incorrect type declarations in Typescript when using Material-UI Higher Order Components can

Currently, I am in the process of upgrading from Material-UI 1.x to the newer version Material-UI 3.9.2. I had several components that were functioning well with Higher Order Components (HOC), but when it comes to migrating them to 3.9.2, I am facing some ...

Exploring the File Selection Dialog in Node.js with TypeScript

Is it possible to display a file dialog in a Node.js TypeScript project without involving a browser or HTML? In my setup, I run the project through CMD and would like to show a box similar to this image: https://i.stack.imgur.com/nJt3h.png Any suggestio ...

How can I prevent node_module from being included when using the include directive in tsconfig.json?

Many developers are excluding the node_modules folder in their tsconfig.json. I, on the other hand, am using the include directive with specific folder patterns. Do I really need to exclude node_modules? And what about third-party libraries that aren' ...

Generate a blueprint for a TypeScript interface

In my coding project, I've been noticing a pattern of redundancy when it comes to creating TypeScript interfaces as the code base expands. For example: interface IErrorResponse { code: number message: string } // Feature 1 type FEATURE_1_KEYS = ...

There are several InputBase elements nested within a FormControl

There seems to be an issue: Material-UI: It appears that there are multiple InputBase components within a FormControl, which is not supported. This could potentially lead to infinite rendering loops. Please only use one InputBase component. I understand ...

how to implement dynamic water fill effects using SVG in an Angular application

Take a look at the code snippet here HTML TypeScript data = [ { name: 'server1', humidity: '50.9' }, { name: 'server2', humidity: '52.9', }, { name: 'server3', humidity: ...

Mapping intricate entities to intricate DTOs using NestJS and TypeORM

Currently, I am using the class-transformer's plainToClass(entity, DTO) function to transform entities into DTO objects. In addition, I have implemented the transform.interceptor pattern as outlined in this source. I make use of @Expose() on propert ...

Creating an endless scrolling feature with Ionic 3

My tech stack includes symfony3 and FosRestBundle for the backend, and Ionic 3 for the frontend development. While attempting to implement an InfiniteScroll feature following the Ionic documentation, I encountered an issue where only the loading text and ...

Leveraging symbols as object key type in TypeScript

I am attempting to create an object with a symbol as the key type, following MDN's guidance: A symbol value may be used as an identifier for object properties [...] However, when trying to use it as the key property type: type obj = { [key: s ...

Customizing form validation in React using Zod resolver for optional fields

I am currently working on creating a form using React-hook-form and zod resolver. My goal is to have all fields be optional, yet still required despite being marked as optional in the zod schema: const schema = z.object({ name: z.string().min(3).max(50 ...

Error message stating: "Form control with the name does not have a value accessor in Angular's reactive forms."

I have a specific input setup in the following way: <form [formGroup]="loginForm""> <ion-input [formControlName]="'email'"></ion-input> In my component, I've defined the form as: this.log ...

Synchronizing Form Data in Angular 5: Pass and Populate Dropdowns between Components

I have developed a unique form (material dialog modal) that allows users to create an account. When the user clicks on the Register button, their created account should appear in a dropdown menu without redirecting or reloading the current page. I am facin ...

Encountering an issue with importing a component in a mixin in NuxtJS

Currently, my main technologies are Nuxtjs and Nuxt-property-decorator To prevent repeating a certain method, I created a mixin This method requires the use of a component (Alert component) In order to use the component in the mixin, I imported it Howe ...

Issue in Typescript: The method `clear` or `send` is not recognized in type `unknown` within Protractor framework

Having trouble using clear and sendKeys in Protractor with TypeScript. Could it be that I am missing certain dependencies, as even the click function is giving errors? I have attempted various solutions from Protractor clear() not working, but unfortunate ...

What is the best way to choose the member variables in this specific data structure?

I have been assigned the task of retrieving the cities from various countries, but I am unsure of the best approach to do so. How can I easily extract city names like: For example, for USA it would be NYC and SFO. I attempted using the code snippet cityD ...

Issue when calling .create() method on Mongoose schema: "this expression is not callable" error in TypeScript

Encountering an error with the .create method on a mongoose model in Next JS while making a call in an API route. The get request is functioning properly... The structure: pages>API>task.tsx import dbConnect from "../../util/dbconnect"; im ...

Requesting for a template literal in TypeScript:

Having some trouble with my typescript code, it is giving me an error message regarding string concatenation, const content = senderDisplay + ', '+ moment(timestamp).format('YY/MM/DD')+' at ' + moment(timestamp).format(&apo ...

Node C++ Addon Typescript declaration file

I have developed a Node C++ Addon that wraps a class similar to the one outlined in the official Node documentation. By using require(), I am able to access my addon and retrieve the constructor for my class in order to instantiate it. const { MyClass } = ...