diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index 0fd0d4b172..e7f063d086 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -134,7 +134,6 @@ export default function dom( }); if (component.compile_options.dev) { - // TODO check no uunexpected props were passed, as well as // checking that expected ones were passed const expected = props.filter(prop => !prop.initialised); @@ -395,6 +394,16 @@ export default function dom( return $name; }); + let unknownPropsCheck; + if (component.compile_options.dev && writable_props.length) { + unknownPropsCheck = deindent` + const writableProps = [${writable_props.map(prop => `'${prop.export_name}'`).join(', ')}]; + Object.keys($$props).forEach(key => { + if (!writableProps.includes(key)) console.warn(\`<${component.tag}> was created with unknown attribute '\${key}'\`); + }); + `; + } + builder.add_block(deindent` function ${definition}(${args.join(', ')}) { ${reactive_store_declarations.length > 0 && `let ${reactive_store_declarations.join(', ')};`} @@ -404,6 +413,8 @@ export default function dom( ${resubscribable_reactive_store_unsubscribers} ${component.javascript} + + ${unknownPropsCheck} ${component.slots.size && `let { $$slots = {}, $$scope } = $$props;`} diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index 98c2837ab7..9b6ef447b4 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -65,6 +65,11 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { name } = $$props; + const writableProps = ['name']; + Object.keys($$props).forEach(key => { + if (!writableProps.includes(key)) console.warn(` was created with unknown attribute '${key}'`); + }); + $$self.$set = $$props => { if ('name' in $$props) $$invalidate('name', name = $$props.name); }; @@ -93,4 +98,4 @@ class Component extends SvelteComponentDev { } } -export default Component; \ No newline at end of file +export default Component; diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index c1391475b2..006b25aba5 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -151,6 +151,11 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { things, foo, bar, baz } = $$props; + const writableProps = ['things', 'foo', 'bar', 'baz']; + Object.keys($$props).forEach(key => { + if (!writableProps.includes(key)) console.warn(` was created with unknown attribute '${key}'`); + }); + $$self.$set = $$props => { if ('things' in $$props) $$invalidate('things', things = $$props.things); if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); @@ -215,4 +220,4 @@ class Component extends SvelteComponentDev { } } -export default Component; \ No newline at end of file +export default Component; diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index f5daa7dad7..7bc58434a8 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -151,6 +151,11 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { things, foo } = $$props; + const writableProps = ['things', 'foo']; + Object.keys($$props).forEach(key => { + if (!writableProps.includes(key)) console.warn(` was created with unknown attribute '${key}'`); + }); + $$self.$set = $$props => { if ('things' in $$props) $$invalidate('things', things = $$props.things); if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); @@ -191,4 +196,4 @@ class Component extends SvelteComponentDev { } } -export default Component; \ No newline at end of file +export default Component; diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index 12e8a983d0..e181486512 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -65,6 +65,11 @@ function instance($$self, $$props, $$invalidate) { let bar; + const writableProps = ['foo']; + Object.keys($$props).forEach(key => { + if (!writableProps.includes(key)) console.warn(` was created with unknown attribute '${key}'`); + }); + $$self.$set = $$props => { if ('foo' in $$props) $$invalidate('foo', foo = $$props.foo); }; @@ -97,4 +102,4 @@ class Component extends SvelteComponentDev { } } -export default Component; \ No newline at end of file +export default Component; diff --git a/test/runtime/samples/dev-warning-unknown-props/Foo.svelte b/test/runtime/samples/dev-warning-unknown-props/Foo.svelte new file mode 100644 index 0000000000..cebe5fd571 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props/Foo.svelte @@ -0,0 +1,5 @@ + + +
{foo}
diff --git a/test/runtime/samples/dev-warning-unknown-props/_config.js b/test/runtime/samples/dev-warning-unknown-props/_config.js new file mode 100644 index 0000000000..31b605e214 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props/_config.js @@ -0,0 +1,9 @@ +export default { + compileOptions: { + dev: true + }, + + warnings: [ + ` was created with unknown attribute 'fo'` + ] +}; diff --git a/test/runtime/samples/dev-warning-unknown-props/main.svelte b/test/runtime/samples/dev-warning-unknown-props/main.svelte new file mode 100644 index 0000000000..1566cf3e41 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props/main.svelte @@ -0,0 +1,5 @@ + + +