I have two objects of the same interface:
interface Project {
_id?: string
title: string
description: string
goal: string
tasks?: Task[]
createdAt?: Date
updatedAt?: Date
}
One contains all the above fields and the other should contain some or all of this: title / description / goal.
I want to assign from second to the first only for the relevant key and only if there is a valid value.
what I got so far:
const updateProjectUtil = (target: Project, update: Project): Project => {
Object.keys(update).forEach(key => {
const k = key as keyof Project;
if (target.hasOwnProperty(k) && update[k]) {
target[k] = update[k] // this line get a typescript error
}
})
return target;
}
I am getting an error:
Type 'string | Task[] | Date | undefined' is not assignable to type 'string & Task[] & Date'. Type 'undefined' is not assignable to type 'string & Task[] & Date'. Type 'undefined' is not assignable to type 'string'.
I tried using Object.entries but it doesn't seem to have any effect.
The bigger picture: I am using Node.js and Express to build a RESTful API. This belongs to the controller of the update route which get the update object from the client side and the target object from the db (MongoDB), changes what fields it needs and returns the data to the client side after saving to the db.
What can I do to make it work? Thanks.
CodePudding user response:
Try
interface Project {
[key: string]: unknown // indexable
_id?: string
title: string
description: string
goal: string
tasks?: Task[]
createdAt?: Date
updatedAt?: Date
}
I think this is missing an index signature.
CodePudding user response:
When I was trying to run your code, I got another error. Not sure if it's a mistake in your question, but the code below works on my side:
type Task = {
name: string
}
interface Project {
_id?: string
title: string
description: string
goal: string
tasks?: Task[]
createdAt?: Date
updatedAt?: Date
}
const updateProjectUtil = (target: Project, update: Project): Project => {
let result = { ...target }
Object.keys(update).forEach(key => {
const k = key as keyof Project;
const updatingValue = update[k]
if (target.hasOwnProperty(k) && updatingValue) {
result = { ...result, [k]: updatingValue }
}
})
return result;
}
I also changed the function to not modify the input parameter target, since you return it anyway
