0

I'm trying to apply a transformation function (dt: Date) => Date to all given Date properties of an object. I think I'm close but still stuck. Note that I'm trying to do it as type-safely as possible.

What I have so far is:

const transform = (dt: Date) => dt;

function process<T extends { [k in K]: Date }, K extends keyof T>(obj: T, ...props: K[]) {
    props.forEach(p => (obj[p] = transform(obj[p])));
}

The problem with the above process function is that it's failing in the assignment obj[p] = transformDate(obj[p]) part saying that:

Type 'Date' is not assignable to type 'T[K]'.

But at the same time it seems to recognize T[K] is a Date as it doesn't complain with transform(obj[p]).

How can I update the above function to work?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
dcg
  • 4,187
  • 1
  • 18
  • 32

1 Answers1

2

It works, when you use getDate and setDate instead of direct assigning. Depends whenever this is usable for your case. It can do basically the same thing, but it is little bit less readable.

const transform = (dt: Date) => dt;

function process<T extends { [k in K]: Date }, K extends keyof T>(obj: T, ...props: K[]) {
  for (let key of props) {
    let transformed = transform(obj[key])
    obj[key].setDate(transformed.getDate())
  }
}

I think the problem is more described in this answer (Cause 1) to somewhat similar question.

You can also cast the date object, like this:

const transform = (dt: Date) => dt;

function process<F extends Date, T extends { [k in K]: F }, K extends keyof T>(obj: T, ...props: K[]) {
  for (let key of props) {
    obj[key] = <T[K]> transform(obj[key])
  }
}

This should still remain type safe.

MaBed
  • 178
  • 8
  • 1
    Yes, I finally ended up casting the `transform`'s result - thanks for the link you left above ;) – dcg May 03 '23 at 22:24