Javascript 使用Typescript中的新对象更新常量对象的所有属性
我想用相同类型的新对象更新类型为Javascript 使用Typescript中的新对象更新常量对象的所有属性,javascript,typescript,Javascript,Typescript,我想用相同类型的新对象更新类型为IMessage的对象 interface IMessage { id: string, text: string, // and many more attributes } const message: IMessage = { id: "_id", text: "old text", // and many more attributes } const newMessage: IMessage = { id: "_id",
IMessage
的对象
interface IMessage {
id: string,
text: string,
// and many more attributes
}
const message: IMessage = {
id: "_id",
text: "old text",
// and many more attributes
}
const newMessage: IMessage = {
id: "_id",
text: "new text"
// and many more attributes
}
我希望更新后的消息
的值与新消息
的值完全相同,但我不能只重新分配消息
对象,因为消息
声明为常量
。这就是我目前所拥有的
const updateMessage = (message: any, newMessage: typeof message): void => {
for (const attr in newMessage) {
if (attr !== "id" && newMessage.hasOwnProperty(attr)) {
message[attr] = newMessage[attr];
}
}
};
此功能正在运行。但是在这个函数中,我必须声明
(message:any,newMessage:typeof message)
,否则Typescript将抛出一个警告元素隐式地具有“any”类型,因为类型“IMessage”没有索引签名。如何使此函数仅接受类型为IMessage
的参数?您可以使用TS泛型类型来实现此功能
function updateMessage <T>(message: T, newMessage: T): void {
for (const attr in newMessage) {
if (attr !== "id" && newMessage.hasOwnProperty(attr)) {
message[attr] = newMessage[attr];
}
}
};
函数updateMessage(message:T,newMessage:T):无效{
for(新消息中的常量属性){
if(attr!=“id”&&newMessage.hasOwnProperty(attr)){
消息[attr]=新消息[attr];
}
}
};
然后在调用函数时传递类型
updateMessage(message,newMessage)
关于泛型的TS文档:U可以为此使用TS泛型类型
function updateMessage <T>(message: T, newMessage: T): void {
for (const attr in newMessage) {
if (attr !== "id" && newMessage.hasOwnProperty(attr)) {
message[attr] = newMessage[attr];
}
}
};
函数updateMessage(message:T,newMessage:T):无效{
for(新消息中的常量属性){
if(attr!=“id”&&newMessage.hasOwnProperty(attr)){
消息[attr]=新消息[attr];
}
}
};
然后在调用函数时传递类型
updateMessage(message,newMessage)
关于泛型的TS文档:您对使用泛型有什么想法?它将所有自己的和可枚举的属性复制到它的第一个参数中,就像您所做的那样。豁免id
会有点小问题,但您可以使用。像这样:
const updateMessage = (message: IMessage, newMessage: IMessage): void => {
const { id, ...nm } = newMessage; // make nm from newMessage without id prop
Object.assign(message, nm); // update message with nm
};
这应该与原始的updateMessage()
函数一样,没有类型错误。注意,这并不是特别的类型安全,因为Object.assign()
的类型允许任何参数。您可以自己进行键入,以确保后续参数不会添加任何意外属性,如下所示:
const safeAssign: <T>(target: T, ...args: Partial<T>[]) => T = Object.assign;
const updateMessage = (message: IMessage, newMessage: IMessage): void => {
const { id, ...nm } = newMessage;
safeAssign(message, nm);
};
const safeAssign:(目标:T,…args:Partial[])=>T=Object.assign;
const updateMessage=(消息:IMessage,newMessage:IMessage):void=>{
const{id,…nm}=newMessage;
安全分配(消息,nm);
};
但它在运行时的行为是相同的
好吧,希望这会有帮助;祝你好运
您对使用的想法是什么?它将所有自己的和可枚举的属性复制到它的第一个参数中,就像您所做的那样。豁免id
会有点小问题,但您可以使用。像这样:
const updateMessage = (message: IMessage, newMessage: IMessage): void => {
const { id, ...nm } = newMessage; // make nm from newMessage without id prop
Object.assign(message, nm); // update message with nm
};
这应该与原始的updateMessage()
函数一样,没有类型错误。注意,这并不是特别的类型安全,因为Object.assign()
的类型允许任何参数。您可以自己进行键入,以确保后续参数不会添加任何意外属性,如下所示:
const safeAssign: <T>(target: T, ...args: Partial<T>[]) => T = Object.assign;
const updateMessage = (message: IMessage, newMessage: IMessage): void => {
const { id, ...nm } = newMessage;
safeAssign(message, nm);
};
const safeAssign:(目标:T,…args:Partial[])=>T=Object.assign;
const updateMessage=(消息:IMessage,newMessage:IMessage):void=>{
const{id,…nm}=newMessage;
安全分配(消息,nm);
};
但它在运行时的行为是相同的
好吧,希望这会有帮助;祝你好运
您可以使用扩展运算符const updateMessage={…message,…newMessage}
这将在updateMessage
中复制两个objectc的属性,它将用second@ajuni880我需要更新消息的属性
,不创建新对象,并且不能使用let
声明message
?你将能够reassign@ajuni880这就是重点。我有很多原因不能将消息
声明为let
。其中之一是你将违反不可变规则。这就是为什么我决定使用Typescript作为我理解的第一个地方。您可以检查这一点。您可以使用扩展运算符const updateMessage={…message,…newMessage}
这将在updateMessage
中复制两个objectc的属性。它将使用second@ajuni880我需要更新消息的属性
,不创建新对象,并且不能使用let
声明message
?你将能够reassign@ajuni880这就是重点。我有很多原因不能将消息
声明为let
。其中之一是你将违反不可变规则。这就是为什么我决定使用Typescript作为我理解的第一个地方。您可以检查这一点,因为您的代码抛出了语法错误。这是因为箭头函数是正确的,编辑了对旧函数的回答。它对你有用吗?你的代码抛出了一个语法错误。这是因为箭头函数是正确的,编辑了对旧函数的回答。对你有用吗?