Which is better: Nested Object - Interface or Record type?

I have an Object with unknown length where each item can either have a true/false value or another Object with true/false values. The structure is limited to just two dimensions.

const items: SOMETYPE = {
  a: true,
  b: {
    ba: true,
    bc: false,
    bd: true,
  },
  c: false,
  // etc...
}

Should I define this object using an interface with [] brackets, or the same thing but as a type? Which option is more common and standard when checking this kind of object?

I could also use Record inside Record for this purpose.

All approaches work, but which one is considered the most "correct" or best practice? Is there a better way?

interface ItemsInterface {
  [name: string]: boolean | { [name: string]: boolean }
}

type ItemsType = {
  [name: string]: boolean | { [name: string]: boolean }
}

type ItemsTypeRecord = Record<string, boolean | Record<string, boolean>>

Answer №1

According to y2bd, the Record<K, T> type is essentially the same as an index signature:

/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

In the scenario provided with ItemsInterface, ItemsType, and

ItemsTypeRecord</code, they are almost identical with the exception that <code>ItemsInterface
can be extended (since it's an interface), while the others cannot be extended (as they are type aliases).

The only noticeable difference occurs when dealing with recursive types:

interface RecInterface {
  [name: string]: boolean | RecInterface
}

type RecType = {
  [name: string]: boolean | RecType
}

type RecTypeRecord = Record<string, boolean | RecTypeRecord>
//   ~~~~~~~~~~~~~
// Type alias 'RecTypeRecord' circularly references itself.

The last example fails to compile. This could be attributed to TypeScript allowing recursive type aliases in conditional type expressions (T extends U ? V : W) and in object types (like RecType). However, since RecTypeRecord doesn't directly fall under object type and uses Record, TypeScript struggles to determine that the type isn't endless.

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

calls to res.send and res.render

I'm currently trying to determine if it's possible to use res.send(data) and res.render('reports') simultaneously in my code. To provide more details, when I navigate to '/reports', on the server side I am executing a REST ca ...

Learn the method of converting a new Date object into dd mm yy format, specifically 09-07-2020, with a solution given by me for achieving this

For those seeking a solution to retrieve the jQuery date 30 days prior in the format dd-mm-yy: var today = new Date() var priorDate = new Date().setDate(today.getDate() +30) which will provide the date before 30 days in the format 1142 ...

Constantly scrolling screen in android Webview

When working with an Android web view, I encountered a bug related to infinite scrolling. Interestingly, removing the routerLink in certain pages resolved the issue, but not consistently across all cases. Is there a way to address this bug from the Android ...

Tips and tricks for retaining the collapsed state upon reloading Bootstrap 5

Just diving into the world of bootstrap and javascript. How do I save the collapsed state to make sure it stays even after refreshing the page? <p> <button class="btn btn-primary" type="button" data-bs-toggle="collapse&q ...

Having difficulty focusing on the Dropdown component in Primereact

I've been attempting to focus on the "Dropdown" component from primereact, but for some reason, the focus isn't shifting to the desired component. Initially, I tried using the autoFocus property as instructed in the documentation here. However, ...

"Enhance your Vue.js application with the powerful capabilities of vue3-easy

I am currently working on a Vue.js project utilizing the "vue3-easy-data-table" library and following the style recommendations outlined on this particular webpage: Despite attempting to apply the following CSS properties: --easy-table-body-even-row-font ...

SSE and the power of NodeJS through Express

Having trouble receiving SSE events in the browser. This is the server-side code (using Express): app.all('/callme', function(req, res){ res.writeHead(200, { 'Connection': 'keep-alive', 'Content-Type&apo ...

Assign a value to a FormControl in Angular 6

I have 60 properties linked to 60 controls through the mat-tab in a form. When it comes to editing mode, I need to assign values to all the controls. One approach is as follows: this.form.controls['dept'].setValue(selected.id); This involves l ...

magnific popup: trigger the display by clicking on an element other than the image

A recent request from the client calls for the image caption to cover the thumbnail fully when hovered over. To meet this requirement, I now need to enable clicking on the caption to open Magnific Popup rather than using the <a> tag. Here is what I h ...

The loading cursor in IE7 flickers incessantly, causing the webpage to lag and become un

When I move my cursor and click in text fields, the page becomes unresponsive and shows a wait cursor. If you're curious to see this issue in action, check out this video. This problem is specific to IE7. I've attempted to identify any ajax re ...

What is the best way to transform the response data received from axios into a different response format?

After accessing response.data, I am getting a result like:  [{…}, {…}] If I expand it, here is how it looks: [ 0: {...}, 1: {...} ] I have attempted various methods to extract the values, including using a for loop, but it results in an infinite ...

Troubleshooting problem with nested object in AngularJS data table

For my project, I am utilizing an angular js datatable and currently trying to access the following object: "finalizedArr":[ { "treaceId":"KYC454353545", "approval":[ ...

Tips for displaying a download prompt in a new window using a Bootstrap modal?

When attempting to implement a download functionality in a normal HTML page, the code provided below successfully starts the download in a separate window. However, when using the same code within a bootstrap modal form, it does not work. What other step ...

Reorder the Polymer dom-repeat element following a modification in the child component's value

My Polymer dom-repeat list is working fine on the initial value sorting for the children. However, when I update a value within a child element, the sort order of the list does not reflect the changes. What is the best way to achieve this? <body> ...

Utilizing Lazy Loading for the search HomeComponent, which is not being utilized within the module

I'm facing an issue with Lazy Loading in Angular. I have a module called ShopCartModule that needs to be implemented using Lazy Loading. In addition to the ShopCartModule, I also have the AppModule and the CoreModule. This is my AppModule: @NgModul ...

Exploring the integration of PostgreSQL into JavaScript

As a beginner in JavaScript, I am looking to create a web page that can store data in a database. Can anyone provide guidance on what resources or materials I should study to learn more about this process? ...

Error: TypeScript is unable to find the property URL within the specified type. Can you help

Currently, I am honing my skills in TypeScript and encountering a problem. I am a bit confused about how to define the type for the URL when I am setting the mix here. Obviously, the URL is supposed to be a string, and this specific scenario is within the ...

Utilizing the Data Fetched from a Factory GET Request in an AngularJS Controller

Recently, I developed an Angular factory specifically designed for fetching JSON data. Utilizing the $resource alongside the get method has allowed me to successfully retrieve a JSON object from the server. Within this object are multiple child objects tha ...

What is the best way to declare the data type of an endless generator?

Below is an example of JavaScript code: /** * Generates a sequence of numbers. * * @param {number} i - The starting number. * @yields {number} The next number. */ function* gen(i) { while (true) { yield i++; } } const g = gen(1); // Case 1 ...

Need help with the HTML scrolling problem? I need to remove the buttons, horizontal option, and keep the snapping feature enabled

Is there a way to achieve a cool scroll effect that locks each div id on the page? I'm unsure of how to do this. Check out the project at I've removed the CSS as it's unnecessary, but you can still view the project on repl.it here: https:// ...