diff --git a/packages/protobuf-test/src/to-plain-message.test.ts b/packages/protobuf-test/src/to-plain-message.test.ts index d866f4b25..ebb6646f9 100644 --- a/packages/protobuf-test/src/to-plain-message.test.ts +++ b/packages/protobuf-test/src/to-plain-message.test.ts @@ -261,6 +261,14 @@ describe("toPlainMessage", () => { const act = toPlainMessage(new WrappersMessage(exp)); expect(act).toEqual(exp); }); + describe("on plain messages", () => { + const exp: PlainMessage = { + messageField: undefined, + repeatedMessageField: [], + }; + const act = toPlainMessage(exp); + expect(act).toBe(exp); + }); }); function expectPlainObject(value: unknown) { diff --git a/packages/protobuf/src/to-plain-message.ts b/packages/protobuf/src/to-plain-message.ts index 8795f42b2..f88468369 100644 --- a/packages/protobuf/src/to-plain-message.ts +++ b/packages/protobuf/src/to-plain-message.ts @@ -18,14 +18,21 @@ import { Message } from "./message.js"; import type { AnyMessage, PlainMessage } from "./message.js"; /** - * toPlainMessage returns a new object by striping + * toPlainMessage returns a new object by stripping * all methods from a message, leaving only fields and * oneof groups. It is recursive, meaning it applies this * same logic to all nested message fields as well. + * + * If the argument is already a plain message, it is + * returned as-is. */ export function toPlainMessage>( - message: T, + message: T | PlainMessage, ): PlainMessage { + if (!(message instanceof Message)) { + return message; + } + const type = message.getType(); const target = {} as AnyMessage; for (const member of type.fields.byMember()) {