How to specify a single kind of JavaScript object using Typescript

Let's say we have an object structured as follows:

const obj = [
  { createdAt: "2022-10-25T08:06:29.392Z", updatedAt: "2022-10-25T08:06:29.392Z"},
  { createdAt: "2022-10-25T08:06:29.392Z", animal: "cat"}
]

We want to develop a function that arranges the objects by the "createdAt" field, which is guaranteed to exist in each object. The function prototype would look like this:

export const sortArrayByCreatedAt = (arr: TypeArr) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

How should we define the type of the 'arr' parameter?

Type TypeArr {
  createdAt: string
}

Is it considered best practice to specify the type of the only known variable?

In my opinion, when someone else looks at this function, they might assume that the 'obj' array solely consists of objects with the 'createdAt' property. However, I couldn't come up with a better alternative.

Answer №1

In my approach, I would define the TypeArr as an interface and implement the sort method as a generic function to maintain the existing return type.

export const sortArrayByCreatedAt = <T extends TypeArr>(arr: Array<T>) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

interface TypeArr{
    createdAt :string
}

const obj = [
  { createdAt: "2022-10-25T08:06:29.392Z", updatedAt: "2022-10-25T08:06:29.392Z"},
  { createdAt: "2022-10-25T08:06:29.392Z", animal: "cat"}
]

const sorted = sortArrayByCreatedAt(obj);

Interactive Playground

Answer №2

It appears that when passing the array to the function, you are also returning the same array. The current return type is TypeArr[], which does not accurately represent the additional properties within the objects.

To address this issue, I would suggest making the function sortArrayByCreatedAt generic.

export const sortArrayByCreatedAt = <T extends { createdAt: string }[]>(arr: T): T => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

This modification ensures that the input type matches the return type.

Answer №3

To incorporate optional properties in types or interfaces, you can simply add a question mark ? like this:

type MyType = {
    createdAt: string;
    updatedAt?: string;
    animal?: string;
}
interface MyInterface {
    createdAt: string;
    updatedAt?: string;
    animal?: string;
}

When typing an array of the object, use MyType[] or MyInterface[], for example:

export const sortArrayByCreatedAt = (arr: MyType[]) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

Answer №4

To create an interface with optional properties, simply add a question mark ? before the property name:

interface AnimalDetails {
  species: string
  habitat?: string
  diet?: string
}

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

window.onresize = function() { // code here

Here's an example of code I've been working on: $(document).ready(function (e) { adjustSize(); $(window).resize(adjustSize); function adjustSize() { var windowWidth = parseInt($(window).width()); if (windowWidth > ...

How come my directive is being updated when there are changes in a different instance of the same directive?

For the purpose of enabling Angular binding to work, I developed a straightforward directive wrapper around the HTML file input. Below is the code for my directive: angular.module('myApp').directive('inputFile', InputFileDirective); f ...

Steps to retrieve a specific key value from each object in an AJAX request

I am looking to extract the "url" key and its value from the provided code and save it in a variable. I have attempted different methods to isolate the url key as seen in my commented-out code. $.ajax({ type: 'GET', url: "url", // data: da ...

I was able to use the formGroup without any issues before, but now I'm encountering an error

<div class="col-md-4"> <form [formGroup]="uploadForm" (ngSubmit)="onSubmit(uploadForm.organization)"> <fieldset class="form-group"> <label class="control-label" for="email"> <h6 class="text-s ...

Ajax received a response from http 409 and is now parsing it

Hey there! I've been working on parsing out the message object using Ajax, and I'm having a bit of trouble getting a reference to messages.msg. It's strange because it displays perfectly fine in Postman, but for some reason, I can't see ...

Why won't the jQuery function trigger when I click, but only responds when I move the cursor?

I am currently working on a website that includes a basic CSS style switcher. The function responsible for handling the theme button clicks is shown below: <script> $(function() { $(".light").click(function(){ $("link").attr("href", ...

Is it possible for a dash in a GET variable name to cause issues with req.query in NodeJS Express?

I am currently developing a GET endpoint in Node.js using Express to handle the following variable: ?message-timestamp=2012-08-19+20%3A38%3A23 However, I am facing difficulty accessing it through req.query. Whenever I try to access req.query.message-time ...

How to manually close the modal in Next.js using bootstrap 5

Incorporating Bootstrap 5.2 modals into my Next.js application has been smooth sailing so far. However, I've encountered an issue with closing the modal window after a successful backend request. To trigger the modal, I use the data-bs-toggle="modal" ...

Steps to utilize redux in a fresh react class component

Within my App, there are two buttons - one for saving a message and another for creating a new component. import React from "react"; import { connect } from "react-redux"; import { AppState } from "./redux/store"; import { ChatState } from "./redux/chat/t ...

Can AdonisJS 4.1.0 support conditional queries?

I am exploring the capabilities of AdonisJs query builder by referring to their documentation at Currently, I am attempting to replicate a scenario similar to the one demonstrated under the 'Conditional Queries' section: const query = Database. ...

What are some best practices for managing object-level variables in TypeScript and Vue.js?

Uncertain about the optimal approach, I am looking to create a component and leverage some object level variables. Consider the example below: import Vue from "vue" import * as paper from "paper" export default Vue.extend({ template: ` <d ...

Error: Unable to iterate over data.data due to its type

I am attempting to fetch images from the woocommerce API and here is the code I am using: this.config.getWithUrl(this.config.url + '/api/appsettings/get_all_banners/?insecure=cool') .then((data: any) => { this.banners = data.data; consol ...

A dynamic way to refresh select options in HTML with PHP and JavaScript powered by JQuery

Imagine a scenario with the following layout: There is a table called "Regions" with columns "id" and "name". Also, there is another table named "Cities" containing columns "id", "region_id", and "name". How can you efficiently refill an HTML select opt ...

What is the best way to change `props.children` into a JSX element?

When using React functional components, we have the ability to render children in the following way: import React from 'react'; const MyComponent = (props: React.PropsWithChildren) => { return props.children; } However, I encountered an ...

Converting NodeJS newline delimited strings into an array of objects

What is the method for reading a text file as follows: `{'values': [0,1,0], 'key': 0} {'values': [1,1,0], 'key': 1} {'values': [1,1,0], 'key': 1}` using: var fs = require('fs'); fs. ...

Arranging unrelated divs in alignment

http://codepen.io/anon/pen/Gxbfu <-- Here is the specific portion of the website that needs alignment. My goal is to have Onyx Design perfectly aligned with the right side of the navbar, or to have the navbar extend up to the end of "Onyx Design". The ...

Choosing the initial choice with ngFor: A step-by-step guide

I'm having trouble selecting the first option after the user enters their email, but it remains unselected. Any ideas on how to solve this? view image here HTML Code: <label for="login"><b>User:</b></label> <inpu ...

Node's Object.prototype function returns an empty object

When I run Object.prototype in the browser console, I see all the properties and methods within it. However, when I do the same thing in the NodeJS terminal, I get an empty object {}. Can someone explain why this difference occurs? Attached are screenshots ...

Issue: $controller:ctrlreg The controller named 'HeaderCntrl' has not been properly registered

I am encountering an error while working on my AngularJS program. I have defined the controller in a separate file but it keeps saying that the controller is not registered. Can someone please help me understand why this issue is happening? <html n ...

Challenge when providing particular strings in Typescript

Something seems to be wrong with the str variable on line number 15. I would have expected the Typescript compiler to understand that str will only ever have the values 'foo' or 'bar' import { useEffect } from 'react' type Ty ...