diff --git a/src/compile/Compiler.ts b/src/compile/Compiler.ts
index be5ca6c65195..690b837d7901 100644
--- a/src/compile/Compiler.ts
+++ b/src/compile/Compiler.ts
@@ -24,7 +24,8 @@ import { Node, GenerateOptions, ShorthandImport, Ast, CompileOptions, CustomElem
 
 interface Computation {
 	key: string;
-	deps: string[]
+	deps: string[];
+	hasRestParam: boolean;
 }
 
 function detectIndentation(str: string) {
@@ -436,7 +437,6 @@ export default class Compiler {
 			code,
 			source,
 			computations,
-			methods,
 			templateProperties,
 			imports
 		} = this;
@@ -588,15 +588,20 @@ export default class Compiler {
 
 						const param = value.params[0];
 
-						if (param.type === 'ObjectPattern') {
+						const hasRestParam = (
+							param.properties &&
+							param.properties.some(prop => prop.type === 'RestElement')
+						);
+
+						if (param.type !== 'ObjectPattern' || hasRestParam) {
+							fullStateComputations.push({ key, deps: null, hasRestParam });
+						} else {
 							const deps = param.properties.map(prop => prop.key.name);
 
 							deps.forEach(dep => {
 								this.expectedProperties.add(dep);
 							});
 							dependencies.set(key, deps);
-						} else {
-							fullStateComputations.push({ key, deps: null })
 						}
 					});
 
@@ -611,7 +616,7 @@ export default class Compiler {
 						const deps = dependencies.get(key);
 						deps.forEach(visit);
 
-						computations.push({ key, deps });
+						computations.push({ key, deps, hasRestParam: false });
 
 						const prop = templateProperties.computed.value.properties.find((prop: Node) => getName(prop.key) === key);
 					};
diff --git a/src/compile/dom/index.ts b/src/compile/dom/index.ts
index 0a02b664bed1..1eada67e9ee9 100644
--- a/src/compile/dom/index.ts
+++ b/src/compile/dom/index.ts
@@ -67,7 +67,7 @@ export default function dom(
 	const computationDeps = new Set();
 
 	if (computations.length) {
-		computations.forEach(({ key, deps }) => {
+		computations.forEach(({ key, deps, hasRestParam }) => {
 			if (target.readonly.has(key)) {
 				// <svelte:window> bindings
 				throw new Error(
@@ -89,8 +89,10 @@ export default function dom(
 			} else {
 				// computed property depends on entire state object —
 				// these must go at the end
+				const arg = hasRestParam ? `@exclude(state, "${key}")` : `state`;
+
 				computationBuilder.addLine(
-					`if (this._differs(state.${key}, (state.${key} = %computed-${key}(state)))) changed.${key} = true;`
+					`if (this._differs(state.${key}, (state.${key} = %computed-${key}(${arg})))) changed.${key} = true;`
 				);
 			}
 		});
diff --git a/src/shared/utils.js b/src/shared/utils.js
index c431a673f822..1394f55a46d0 100644
--- a/src/shared/utils.js
+++ b/src/shared/utils.js
@@ -25,4 +25,10 @@ export function addLoc(element, file, line, column, char) {
 	element.__svelte_meta = {
 		loc: { file, line, column, char }
 	};
+}
+
+export function exclude(src, prop) {
+	const tar = {};
+	for (const k in src) k === prop || (tar[k] = src[k]);
+	return tar;
 }
\ No newline at end of file
diff --git a/src/utils/annotateWithScopes.ts b/src/utils/annotateWithScopes.ts
index 408de776b253..08ac93387cf3 100644
--- a/src/utils/annotateWithScopes.ts
+++ b/src/utils/annotateWithScopes.ts
@@ -137,7 +137,11 @@ const extractors = {
 
 	ObjectPattern(names: string[], param: Node) {
 		param.properties.forEach((prop: Node) => {
-			extractors[prop.value.type](names, prop.value);
+			if (prop.type === 'RestElement') {
+				names.push(prop.argument.name);
+			} else {
+				extractors[prop.value.type](names, prop.value);
+			}
 		});
 	},
 
diff --git a/test/runtime/samples/object-rest/_config.js b/test/runtime/samples/object-rest/_config.js
new file mode 100644
index 000000000000..7a60f0d5638c
--- /dev/null
+++ b/test/runtime/samples/object-rest/_config.js
@@ -0,0 +1,27 @@
+export default {
+	skip: +/v(\d+)/.exec(process.version)[1] < 8,
+
+	html: `
+		<pre>{"wanted":2}</pre>
+	`,
+
+	test(assert, component, target) {
+		component.set({
+			unwanted: 3,
+			wanted: 4
+		});
+
+ 		assert.htmlEqual(target.innerHTML, `
+			<pre>{"wanted":4}</pre>
+		`);
+
+ 		component.set({
+			unwanted: 5,
+			wanted: 6
+		});
+
+ 		assert.htmlEqual(target.innerHTML, `
+			<pre>{"wanted":6}</pre>
+		`);
+	}
+};
\ No newline at end of file
diff --git a/test/runtime/samples/object-rest/main.html b/test/runtime/samples/object-rest/main.html
new file mode 100644
index 000000000000..e66a89291e61
--- /dev/null
+++ b/test/runtime/samples/object-rest/main.html
@@ -0,0 +1,18 @@
+<pre>{JSON.stringify(props)}</pre>
+<script>
+	export default {
+		data: () => ({
+			unwanted: 1,
+			wanted: 2
+		}),
+
+		helpers: {
+			// prevent this being mixed in with data
+			JSON
+		},
+
+		computed: {
+			props: ({ unwanted, ...x }) => x
+		}
+	};
+</script>
\ No newline at end of file