Number as the Key in Typescript Record<number, string> is allowed

As a newcomer to TypeScript, I am still learning a lot and came across this code snippet that involves the Record utility types, which is quite perplexing for me.

The code functions correctly in the playground environment.

const data = async (name: string, id: number): Promise<Record<number,string>> => {
  const obj = {
    foo: 'bar', //I'm confused why this works even though it's 'number'
  }
  return obj
}

However, the following code does not work (2nd line).

const foo1: Record<string, string> = { foo: 'bar' }
const foo2: Record<number, string> = { foo: 'bar' }

I am unsure about the correct type of data that should be used for the 'key'. Feel free to experiment on TypeScript Playground.

Answer №1

The reason for this is because TypeScript needs to be compatible with JavaScript.

Take a look at this simple JavaScript code:

const foo={
  0:42
}

const x = foo['0'] // number
const y = foo[0] // number

As you can see, in JS you can use both string and number keys for the value 0: 42.

Refer to the documentation for both JS and TS:

JS Explanation

Property names Property names are strings or Symbols. Any other value, including numbers, will be converted into a string. This results in 'value', as 1 is converted to '1'.

TS Explanation

Both types of indexers can be supported, but the type returned from a numeric indexer must be a subtype of the type returned from the string indexer. This is because when indexing with a number, JavaScript actually converts it to a string before indexing an object. Therefore, indexing with 100 (a number) is equivalent to indexing with "100" (a string), so they need to match.

But why is this? And what data type should be used for the 'key'?

TypeScript has a built-in type for keys:

type PropertyKey = string | number | symbol

You can utilize PropertyKey without having to declare it separately, as it's already included.

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 is the concept of NonNullable in typescript and how can it be understood

In TypeScript, the concept of NonNullable is defined as type NonNullable<T> = T extends null | undefined ? never : T For instance, type ExampleType = NonNullable<string | number | undefined>; Once evaluated, ExampleType simplifies to type Exa ...

I'm having trouble with class attributes not functioning properly in TypeScript within Angular. What steps can I take to resolve this issue

Currently, I am in the process of mastering Angular, CSS (particularly Tailwind), HTML, and TypeScript as a means to construct a website. Despite clicking the menu button on the navigation bar thrice, I was puzzled why this.name appeared as undefined duri ...

Ways to manage an excessive number of asynchronous calls?

As a newcomer to Node, I've learned that writing synchronous functions can negatively impact the event loop by causing it to lock up. It's generally better to write everything asynchronously. However, there are cases where using async for everyt ...

What is the best way to handle closing popups that have opened during an error redirection

In my interceptor, I have a mechanism for redirecting the page in case of an error. The issue arises when there are popups already open, as they will not automatically close and the error page ends up appearing behind them. Here's the code snippet re ...

Using Typescript to pass a property as one of the keys in an object's list of values

In my React Native project, I need to pass a string value from one component to another. The different options for the value can be found in the ScannerAction object: export const ScannerAction = { move: 'move', inventory: 'inventory&apo ...

The 'path' property is not found on the 'ValidationError' type when using express-validator version 7.0.1

When utilizing express-validator 7.0.1, I encounter an issue trying to access the path field. The error message indicates that "Property 'path' does not exist on type 'ValidationError'.: import express, { Request, Response } from " ...

React animation failing to render underline animation

After tinkering with the underline animation while scrolling down on Codepen using Javascript, I successfully implemented it. You can check out the working version on Codepen. This animation utilizes Intersection Observer and a generated svg for the underl ...

Utilize Primeng data grid to calculate total sum and display it in the footer section

I have been utilizing primeng datatable in a recent project and am currently facing an issue with calculating the sum in the footer of a row grouping DataTable. The summation needs to occur while data is being edited and new data is being entered. Below i ...

Instance of exported class declared in Typescript

Currently, I am in the process of developing my initial declaration file for a foreign library known as react-native-background-timer. Within this library, there exists a default export that I am uncertain about how to declare within the index.d.ts file. ...

Tips for invoking a function from one React component to another component

Currently, I am working on two components: one is Game and the other is PickWinner. The Game component serves as the parent component, from which I need to call the pickWinner function in the PickWinner component. Specifically, I want to trigger the startP ...

Display a symbol retrieved from the backend server

After receiving a response from the backend server for my Angular 2/4 application, I am presented with an attribute called "connectionStatus". This attribute indicates the status of a database connection, either as "UP" or "DOWN". In order to display this ...

Can I utilize a specific interface type within another interface?

Can I pass an object along with its interface to a React component? Here's a sample of the interface I'd like to incorporate: interface TableProps { ObjectProps: Interface (not functioning properly); objects: Array<ObjectProps>; } Is i ...

Trouble encountered when attempting to call a function within another function in StencilJS

I am currently following a tutorial on building a drag and drop file uploader using StencilJS for some practice and fun. However, I have encountered an error in the code. Below is a snippet of the code, but I can provide more if necessary. @Component({ ...

Encountering a challenge when upgrading to eslint version 9.0.0

Encountering an issue while trying to upgrade eslint to version 9.0.0. ⋊> ~/A/fusion on turborepo ⨯ bun lint 22:21:58 $ eslint packages/*/src/**/* Oops! Something went wrong! :( ESLint: 9.0. ...

Having difficulty retrieving the file from Google Drive through googleapis

I'm currently attempting to retrieve a file from Google Drive using the Googleapis V3, but I keep encountering an error message stating: 'Property 'on' does not exist on type 'GaxiosPromise<Schema$File>'. Below is the c ...

Determine whether an array is void, then proceed to deactivate a button

I am attempting to prevent a button from being clickable if an array is empty, but I am encountering difficulties. <button [disabled]="(users.length ==0 )?true:false">Send mass emails</button> Within the TypeScript file: users: UsersModel[]; ...

Define the format for the output file name in TypeScript

I am trying to change the filename of a TypeScript generated js file. How can I accomplish this? For instance, I currently have MyCompany.ClassA.ts The default output filename is MyCompany.ClassA.js However, I would like the output filename to be MyComp ...

Best method for integrating widget scripts in Angular 5

I am in the process of developing an Angular 5 application and I have encountered a challenge while trying to integrate a widget into one of the components. Following the guidance provided in this particular question, I attempted to add the widget as inst ...

Having trouble with the sleep function in nodejs?

Hey there! I'm currently working on a Node.js function that sends requests using array.map. However, I'm facing a challenge with making the function wait for 4 minutes when an error occurs before sending the next request. I've attempted to u ...

Is there a more efficient method for invoking `emit` in Vue's Composition API from an external file?

Is there a more efficient way to access the emit function in a separate logic file? This is my current approach that is functioning well: foo.js export default (emit) => { const foo = () => { emit('bar') }; return { foo }; } When ...