diff --git a/src/lib/checkbox/checkbox.spec.ts b/src/lib/checkbox/checkbox.spec.ts
index 0fb39a761746..595653355c39 100644
--- a/src/lib/checkbox/checkbox.spec.ts
+++ b/src/lib/checkbox/checkbox.spec.ts
@@ -887,12 +887,12 @@ class CheckboxWithFormDirectives {
}
/** Simple test component with multiple checkboxes. */
-@Component(({
+@Component({
template: `
Option 1
Option 2
`
-}))
+})
class MultipleCheckboxes { }
diff --git a/tools/tslint-rules/onPushChangeDetectionRule.js b/tools/tslint-rules/onPushChangeDetectionRule.js
new file mode 100644
index 000000000000..50ca46a63450
--- /dev/null
+++ b/tools/tslint-rules/onPushChangeDetectionRule.js
@@ -0,0 +1,46 @@
+const Lint = require('tslint');
+const ERROR_MESSAGE = 'Components must use OnPush change detection.';
+
+/**
+ * Rule that enforces that OnPush change detection is used on all @Component declarations.
+ * Files can be whitelisted via `"on-push-change-detection": [true, "\.spec\.ts$"]`.
+ */
+class Rule extends Lint.Rules.AbstractRule {
+ apply(file) {
+ return this.applyWithWalker(new Walker(file, this.getOptions()));
+ }
+}
+
+class Walker extends Lint.RuleWalker {
+ constructor(file, options) {
+ super(...arguments);
+
+ // Whitelist with regular expressions to use when determining which files to lint.
+ const whitelist = options.ruleArguments;
+
+ // Whether the file should be checked at all.
+ this._enabled = !whitelist.length || whitelist.some(p => new RegExp(p).test(file.fileName));
+ }
+
+ visitClassDeclaration(node) {
+ if (!this._enabled || !node.decorators) return;
+
+ node.decorators
+ .map(decorator => decorator.expression)
+ .filter(expression => expression.expression.getText() === 'Component')
+ .filter(expression => expression.arguments.length && expression.arguments[0].properties)
+ .forEach(expression => {
+ const hasOnPushChangeDetection = expression.arguments[0].properties.some(prop => {
+ const value = prop.initializer.getText();
+ return prop.name.getText() === 'changeDetection' && value.endsWith('.OnPush');
+ });
+
+ if (!hasOnPushChangeDetection) {
+ this.addFailureAtNode(expression.parent, ERROR_MESSAGE);
+ }
+ });
+ }
+
+}
+
+exports.Rule = Rule;
diff --git a/tslint.json b/tslint.json
index 2c9ee2c55180..120148206525 100644
--- a/tslint.json
+++ b/tslint.json
@@ -35,6 +35,10 @@
"src/lib",
"src/cdk"
],
+ "on-push-change-detection": [
+ true,
+ "(lib|cdk)\/((?!spec.ts).)*.ts$"
+ ],
"one-line": [
true,
"check-catch",