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

The jQuery panel slider magically appears when you click the button, but refuses to disappear

One issue I am facing on my webpage involves a button that triggers a right panel to open using the jquery and modernizr frameworks. The button is positioned at the far right of the screen. When clicked, it slides to the left along with the panel it reveal ...

Problem with Infragistics radio button not firing change event when value is set manually

After migrating from Angular 11 to 17, I encountered a strange issue with my application's Infragistics radio button. The change event for the radio button does not trigger manually for the first time, but it works fine when changed through the applic ...

"Using Angular's NgFor directive to efficiently organize and collapse data within

I am currently working on displaying API data in a table using ngFor, and I am facing an issue with hiding/showing a specific row of details outside the ngFor loop. Since this line is not within the ngFor loop, I am unable to bind the data accordingly. Can ...

Vue's v-on:click feature stops functioning correctly post-build

I have successfully integrated the Vue slide example from this link into my Angular template. Everything works fine when running ng serve, but after building with ng build and then trying to start it again with ng serve or from the dist folder using npm s ...

What is the best way to trigger UseEffect when new data is received in a material table?

I was facing an issue with calling a function in the material table (https://github.com/mbrn/material-table) when new data is received. I attempted to solve it using the following code. useEffect(() => { console.log(ref.current.state.data); ...

Tips for ensuring that divs resize to match the container while preserving their original proportions:

#container { height: 500px; width: 500px; background-color: blue; } #container>div { background-color: rgb(36, 209, 13); height: 100px; } #one { width: 1000px; } #two { width: 800px; } <div id="container"> <div id="one">&l ...

Utilizing conditional types for type narrowing within a function's body: A comprehensive guide

I created a conditional type in my code that constrains the second argument of my class constructor based on the type of the first argument. Although the type checker correctly limits what I can pass to the constructor, I am struggling to get the compiler ...

Confirm the presence of Cookie and save the data

I'm a beginner in the world of Javascript and Ajax, attempting to save a user's name using cookies. I have created a form where users can input their first name (identified by id = firstName). My goal is to remember this information so that the n ...

Why isn't the correct component being shown by react-router?

I have encountered an issue with my code. When I type localhost:8080 in the browser, it displays the App.js component as expected. However, upon navigating to localhost:8080/#/hello, it still shows the App.js component instead of hello.js. Interestingly, ...

Encountering an Error in Laravel 8: Form Submission Issue - Uncaught TypeError Preventing Property Read

<a href="{{ url('/home') }}">Home</a> <a href="{{ route('logout') }}" onclick="event.preventDefault();document.getElementById('logout-form').submit();">Logout</a> <form ...

How to Trigger a Child Component Function from a Parent Component in React.js

I want to trigger a function in my child component when a button is clicked in the parent component. Parent Component: class Parent extends Component{ constructor(props){ super(props); this.state = { //.. } } ...

Can a Singular Ajax Call be Configured for Multiple Inputs?

Within a PHP file, there is a form tag containing multiple inputs of type submit (essentially buttons) generated automatically by an external PHP script with names like button0, button1, etc. My goal is to utilize AJAX and jQuery to send the value of the c ...

Issue with an Angular filter for formatting a lengthy JSON string onto separate lines within an HTML document

Just starting out with coding and working in Angular, I'm trying to display JSON data from Firebase in HTML. Here's the specific call I'm using: <p>{{workout[0].box.info.training.strength.exercise[1].movement.freetext }}</p> Th ...

I am looking to conceal the y-axis labels and tooltip within the react chart

I am currently working with react-chart-2. I have a line graph that displays a tooltip when hovered over, but I would like to hide this tooltip feature. Additionally, I want to remove the numbers 0, 0.1, 0.2 up to 1 on the left side (y-axis) of the gra ...

navigation menu 'selective emphasis' feature

I have created a JQuery script that will highlight the 'About', 'My Projects', or 'Contact Me' text on the navigation bar when the corresponding section of the page is in view. To achieve this, I am using a scroll() event list ...

Tips for configuring the _document.tsx file in Next.js for optimal performance

I found most of the code for this project in the official documentation example on utilizing styled-components: https://github.com/vercel/next.js/blob/canary/examples/with-styled-components/pages/_document.js However, the example was written in .js and I ...

Can you provide a brief explanation for this bubble sort JavaScript code?

Can someone please explain to me what the line j<len-i is doing in this bubble sort code? I believe removing -i from that line will still make the program work properly, var arr=[3,5,4,7,8,9,30,0,-1]; function bubble_Sort(arr){ var len = arr.length, ...

Storing data using mongoose does not alter the existing information

I encountered an issue with my code while trying to update an object fetched from a MongoDB. The object contains a map with an array, and I am pushing new values to that array within the map successfully. However, even though the object itself reflects the ...

What is the best way to secure videos and other static files with authentication in a next.js web application?

My goal is to provide static content, specifically videos, exclusively to authorized visitors. I want to secure routes so that they are only accessible to authenticated users. However, the challenge arises when trying to display a video on a page located i ...

Selecting the optimal data structure: weighing the benefits of using boolean check versus array .include (balancing performance and redundancy

My objects can have one or more properties assigned, with a total of 5 different properties in my case. To illustrate this, let's use a simple movie example where each movie can be assigned from 5 different genres. I have come up with two methods to ...