Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I update a type on the fly using lodash.set? #225

Open
nandorojo opened this issue Mar 26, 2021 · 7 comments
Open

How do I update a type on the fly using lodash.set? #225

nandorojo opened this issue Mar 26, 2021 · 7 comments
Labels
bug Something isn't working
Projects

Comments

@nandorojo
Copy link

nandorojo commented Mar 26, 2021

🍩 Feature Request

Is your feature request related to a problem?

I have a function that updates the type of an object. It turns milliseconds into date objects.

Here's the idea:

const object = {
  lastUpdated: 1616779693036,
  createdAt: 1616779693019
}

const objectWithDates = msToDates(object, ['lastUpdated'])

typeof objectWithDates.lastUpdated // this should be Date

typeof objectWithDates.createdAt // should be number, since I didn't pass it in the array

Describe the solution you'd like

A way to change the type of each field in the object, dynamically, based on the array of paths I pass.

Describe alternatives you've considered

This is my code currently:

import set from 'lodash.set'
import get from 'lodash.get'
import type { F } from 'ts-toolbelt'

function msToDates<
  Obj extends object,
  Path extends string
>(obj: Obj, paths: F.AutoPath<Obj, Path>[]) {
  const next: Obj = { ...obj }

  paths.forEach((path) => {
    const ms = get(obj, path) 
    set(next, path, new Date(ms)) 
  })

  return next
}

This works well. However, the ReturnType of the ms values I pass to paths is still a number, not a Date.

Teachability, Documentation, Adoption, Migration Strategy

This might already be possible, curious if you have an idea how to do it @millsp. Thank you!

@millsp
Copy link
Owner

millsp commented Mar 29, 2021

Hey @nandorojo , that is because set is mutating and TS cannot keep track of mutations. Instead of a foreach, you should look into returning something like https://lodash.com/docs/4.17.15#mapValues. However, I'm not sure how the types work there. If your object is going to contain other fields than numbers, you might want to implement your own mapped type.

@nandorojo
Copy link
Author

Is there a way to map a type from one to another, where certain fields are changed from number to Date?

type NumToDate<O, Paths> something like that?

@millsp
Copy link
Owner

millsp commented Mar 29, 2021

Yes, I'll post the solution in a few minutes

@nandorojo
Copy link
Author

Sweet, I figure I can use that as the return type of my function

@millsp
Copy link
Owner

millsp commented Mar 29, 2021

Sorry, but I realized that the O.P utilities are behaving in a dissociative way (ie. on par with unions). So, I am not able to make the example work right now. It should have been as simple as this:

/* eslint-disable */

import type { S, F, O } from "ts-toolbelt";

declare function msToDates<O extends object, P extends string>(
  obj: O,
  paths: F.AutoPath<O, P>[]
): O.P.Update<O, S.Split<P, ".">, Date>;

const object = {
  lastUpdated: 1616779693036,
  createdAt: 1616779693019,
  subProperty: {
    milliseconds: 2123154541221
  }
};

const objectWithDates = msToDates(object, [
  "lastUpdated",
  "subProperty.milliseconds"
]);

typeof objectWithDates.lastUpdated;
typeof objectWithDates.createdAt;

I'm going to mark this issue as a bug, because I think most people will want the O.P tools to be associative instead. Associativity is much harder to accomplish, while dissociation could just be done by distributing the path before hand. If you run the example, you will see that unions are produced (dissociative), it defeats the purpose in your use-case and probably any other use-case. Sorry about this!

@millsp millsp added the bug Something isn't working label Mar 29, 2021
@millsp millsp added this to To do in Board via automation Mar 29, 2021
@nandorojo
Copy link
Author

@millsp thanks so much for the details!

@stale
Copy link

stale bot commented Jun 2, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Jun 2, 2021
@stale stale bot closed this as completed Jun 18, 2021
Board automation moved this from To do to Done Jun 18, 2021
@millsp millsp reopened this Sep 3, 2021
Board automation moved this from Done to In progress Sep 3, 2021
@stale stale bot removed the wontfix This will not be worked on label Sep 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Board
  
In progress
Development

No branches or pull requests

2 participants