diff --git a/src/runtime/validation.ts b/src/runtime/validation.ts
index 7d069c56..3c499de4 100644
--- a/src/runtime/validation.ts
+++ b/src/runtime/validation.ts
@@ -1,4 +1,5 @@
import { OwlError } from "./error_handling";
+import { toRaw } from "./reactivity";
type BaseType =
| typeof String
@@ -84,6 +85,7 @@ export function validateSchema(obj: { [key: string]: any }, schema: Schema): str
if (Array.isArray(schema)) {
schema = toSchema(schema);
}
+ obj = toRaw(obj);
let errors = [];
// check if each value in obj has correct shape
for (let key in obj) {
diff --git a/tests/components/__snapshots__/props_validation.test.ts.snap b/tests/components/__snapshots__/props_validation.test.ts.snap
index 9b50aec0..7b167f60 100644
--- a/tests/components/__snapshots__/props_validation.test.ts.snap
+++ b/tests/components/__snapshots__/props_validation.test.ts.snap
@@ -841,6 +841,33 @@ exports[`props validation props are validated whenever component is updated 2`]
}"
`;
+exports[`props validation props validation does not cause additional subscription 1`] = `
+"function anonymous(app, bdom, helpers
+) {
+ let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+ const comp1 = app.createComponent(\`Child\`, true, false, false, false);
+
+ return function template(ctx, node, key = \\"\\") {
+ const props1 = {obj: ctx['obj']};
+ helpers.validateProps(\`Child\`, props1, this);
+ const b2 = comp1(props1, key + \`__1\`, node, this, null);
+ const b3 = text(ctx['obj'].otherValue);
+ return multi([b2, b3]);
+ }
+}"
+`;
+
+exports[`props validation props validation does not cause additional subscription 2`] = `
+"function anonymous(app, bdom, helpers
+) {
+ let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+
+ return function template(ctx, node, key = \\"\\") {
+ return text(ctx['props'].obj.value);
+ }
+}"
+`;
+
exports[`props validation props: list of strings 1`] = `
"function anonymous(app, bdom, helpers
) {
diff --git a/tests/components/props_validation.test.ts b/tests/components/props_validation.test.ts
index 55327611..2ce4b244 100644
--- a/tests/components/props_validation.test.ts
+++ b/tests/components/props_validation.test.ts
@@ -1,5 +1,5 @@
import { makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers";
-import { Component, onError, xml, mount, OwlError } from "../../src";
+import { Component, onError, xml, mount, OwlError, useState } from "../../src";
import { App, DEV_MSG } from "../../src/runtime/app";
import { validateProps } from "../../src/runtime/template_helpers";
import { Schema } from "../../src/runtime/validation";
@@ -682,6 +682,29 @@ describe("props validation", () => {
expect(error!.message).toBe("Invalid props for component 'SubComp': 'p' is missing");
});
+ test("props validation does not cause additional subscription", async () => {
+ let obj = {
+ value: 1,
+ otherValue: 2,
+ };
+ class Child extends Component {
+ static props = {
+ obj: { type: Object, shape: { value: Number, otherValue: Number } },
+ };
+ static template = xml``;
+ }
+ class Parent extends Component {
+ static template = xml``;
+ static components = { Child };
+
+ obj = useState(obj);
+ }
+ const app = new App(Parent, { test: true });
+ await app.mount(fixture);
+ expect(fixture.innerHTML).toBe("12");
+ expect(app.root!.subscriptions).toEqual([{ keys: ["otherValue"], target: obj }]);
+ });
+
test("props are validated whenever component is updated", async () => {
let error: Error;
class SubComp extends Component {