Converting an object's date type to a number in TypeScript

I am looking to modify the designated field within an object from a date type to a timestamp

Desired function

let formData = {
   username: "tom",
   startDate: new Date(),
   endtDate: new Date(),
   ...
}

formData = convertObjectDateToTimestamp(formData, ["startDate", "endDate"]);

// formData
// { username: "tome", startDate: 1629874054212,  endDate: 1629874054212};

** Current function **

function convertObjectDateToTimestamp<
   T extends Record<string, unknown>,
   U extends Array<keyof T>,
>(target: T, keys: U) {
   const obj = { ...target };

   (Object.keys(target) as Array<keyof T>).forEach((key) => {
      const value = obj[key];

      if (keys.includes(key) && value instanceof Date) {
         obj[key] = value.getTime();
         // Type 'number' cannot be assigned to type't [keyof t] '
         // alternative:value.getTime() as any 
      }
   });

   return obj;
}

Answer №1

The issue arises due to the inability to change the type of a variable in TypeScript. When obj is set as the same type as T, changing a property's type from Date to number is not allowed.

To suppress the error, one might consider using

value.getTime() as typeof obj[typeof key]
, but this still results in an incorrect inferred return type of T.

A more precise approach would be to structure the function utilizing KeysMatching:

type KeysMatching<T, V> = {[K in keyof T]-?: T[K] extends V ? K : never}[keyof T];

function objectDateToStamp<
  T extends Record<string, unknown>,
  U extends KeysMatching<T, Date>
>(target: T, keys: readonly U[]): Omit<T, U> & Record<U, number> {
  return Object.fromEntries(
    Object.entries(target).map(([key, value]) => [
      key,
      (keys as readonly string[]).includes(key)
        ? (value as Date).getTime()
        : value,
    ])
  ) as Omit<T, U> & Record<U, number>;
}

let formData = {
  username: "tom",
  startDate: new Date(),
  endDate: new Date(),
};

// { username: string; startDate: number; endDate: number }
objectDateToStamp(formData, ["startDate", "endDate"]);

Playground link

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

Angular 5 APP_INITIALIZER: Provider parse error - Cyclic dependency instantiation not possible

I am utilizing the APP_INITIALIZER token to execute a task upon page load before my Angular application is initialized. The service responsible for this functionality relies on another service located within my CoreModule. The issue at hand seems to be ab ...

Adjust the dimensions of the mat-icon-button

Is there a way to adjust the size of a mat-icon-button? Currently, my icon is set at 24px and I would like to increase it to 48px. I am using mat-icon as the button content, but it seems that mat-icon-button has a fixed size of 40px by 40px. <button ...

What is a more efficient way to optimize the repeating 'for-of' loop?

I am faced with the following code challenge: runA() { const request = []; for (const item of this.items ) { request.push(this.getRequestData(item.prop1)); // want to generalize that } return forkJoin(...request).pipe(x => x); ...

The 'initializeOnMount' property is a necessary requirement within the definition of the 'MoralisProviderInitializedProps' type

I encountered an unexpected issue with the code below: Type '{ children: Element; appId: string | undefined; serverUrl: string | undefined; }' is not compatible with type 'IntrinsicAttributes & MoralisProviderProps'. The property ...

Steer clear of duplicating template literal type entries when dealing with optional routes

My code includes a type called ExtractParams that extracts parameters from a URL string: type ExtractParams<Path extends string> = Path extends `${infer Start}(${infer Rest})` ? ExtractParams<Start> & Partial<ExtractParams<Rest>& ...

When a webpage is moved, the globalProperties variable of "vue3 typescript" is initialized to null

main.ts const app = createApp(App) .use(router) .use(createPinia()) .use(vuetify) .use(vue3GoogleLogin, googleLogin) const globalProps = app.config.globalProperties; globalProps.isDebugMode = true; vue-shim declare ...

Declaring a function in TypeScript triggers an error notification

I encountered a typescript error while running my code stating that "require" is not a function. To resolve this, I declared the function beforehand; however, a new typescript error now occurs saying "Modifiers cannot appear here." Can anyone assist me w ...

The attribute 'listen' is not a valid property for the data type 'NavigateFunction'

Just diving into the world of Typescript and react, I recently made the switch from useHistory to useNavigate in react-router-dom v6. However, when using the navigate.listen(e) method inside the useEffect hook, I am encountering the error "Property ' ...

Error: Disappearing textarea textContent in HTML/TS occurs when creating a new textarea or clicking a button

I've encountered an issue with my HTML page that consists of several textareas. I have a function in place to dynamically add additional textareas using document.getElementById("textAreas").innerHTML += '<textarea class="textArea"></text ...

A guide for finding a specific string within a subset of an array

I have an array containing various substrings, and I want to pass if at least one of those substrings contains the specific value I am searching for. Value1 = [ "Grape | 100 |Food Catering Service", "Apple | 100,000m |Food Catering Servi ...

Guide for building a Template-driven formArray in Angular

I am currently implementing a fixed number of checkboxes that are being bound using a for loop. <ul> <li *ngFor="let chk of checkboxes"> <input type="checkbox" [id]="chk.id" [value]="chk.value&q ...

Integrating React frontend with Node JS backend on Kubernetes platform

Seeking guidance on the best approach for making API requests from a React Frontend Application to a Node JS backend application in a Kubernetes environment. Both are hosted within the same container, following this dockerfile structure: COPY frontend/pack ...

Utilizing a created OpenAPI client within a React application

Using the command openapi-generator-cli generate -i https://linktomybackendswagger/swagger.json -g typescript-axios -o src/components/api --additional-properties=supportsES6=true, I have successfully generated my API client. However, despite having all th ...

Issue with Component in Angular not functioning properly with proxy construct trap

Currently working with Angular 17, I have a straightforward decorator that wraps the target with Proxy and a basic Angular component: function proxyDecorator(target: any) { return new Proxy(target, { construct(target: any, argArray: any[], newTarget: ...

Strategies for effectively searching and filtering nested arrays

I'm facing a challenge with filtering an array of objects based on a nested property and a search term. Here is a sample array: let items = [ { category: 15, label: "Components", value: "a614741f-7d4b-4b33-91b7-89a0ef96a0 ...

Tips for successfully passing a prop to a custom root component in material-ui@next with TypeScript

Is there a way to properly render a ListItem component with react-router Link as the root component? Here's the code snippet in question: <ListItem to="/profile" component={Link} > Profile ...

TypeError in TypeScript: Unable to find property 'key' in type 'HTMLAttributes<HTMLLIElement>'

While attempting to destructure the key property from an object, TypeScript is raising an error stating that Property 'key' does not exist on type 'HTMLAttributes<HTMLLIElement> However, upon logging the props object using console.log ...

Exploring image caching in Ionic 2 using TypeScript similar to the functionality of Picasso

Looking for a solution for image caching in Ionic 2 with typescript, but all I can find is for Ionic 1. Any ideas? Tried to understand the code from this link but struggling https://github.com/BenBBear/ionic-cache-src ...

Shifting a collection of dictionaries using a fixed text value

My scenario involves three variables with the same type: const foo = { name: "foo", age: 12, color: "red" } as const; const bar = { name: "bar", age: 46, color: "blue" } as const; const baz = { name: "baz", ...

An error has occurred during parsing: An unexpected token was found, a comma was expected instead

I encountered an error while running my program (vue3 + element plus), and I'm unsure about the cause. Can someone please assist me? Below is the error description along with an image: 56:23 error Parsing error: Unexpected token, expected "," (11 ...