From 0b2b887c06f2582d812a45f7a8deb82f52d82a84 Mon Sep 17 00:00:00 2001 From: Niles Date: Tue, 11 Feb 2020 20:25:46 -0600 Subject: [PATCH 1/3] feat(eslint-plugin): [ban-types] allow banning null and undefined (#821) Co-authored-by: Brad Zacher --- packages/eslint-plugin/src/rules/ban-types.ts | 35 ++++++++++--- .../tests/rules/ban-types.test.ts | 51 +++++++++++++++++++ 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index d15d822de06e..429b5fd6895c 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -23,7 +23,11 @@ function removeSpaces(str: string): string { } function stringifyTypeName( - node: TSESTree.EntityName | TSESTree.TSTypeLiteral, + node: + | TSESTree.EntityName + | TSESTree.TSTypeLiteral + | TSESTree.TSNullKeyword + | TSESTree.TSUndefinedKeyword, sourceCode: TSESLint.SourceCode, ): string { return removeSpaces(sourceCode.getText(node)); @@ -113,18 +117,21 @@ export default util.createRule({ }, ], create(context, [{ types }]) { - const bannedTypes: Types = Object.keys(types).reduce( - (res, type) => ({ ...res, [removeSpaces(type)]: types[type] }), - {}, + const bannedTypes = new Map( + Object.entries(types).map(([type, data]) => [removeSpaces(type), data]), ); function checkBannedTypes( - typeNode: TSESTree.EntityName | TSESTree.TSTypeLiteral, + typeNode: + | TSESTree.EntityName + | TSESTree.TSTypeLiteral + | TSESTree.TSNullKeyword + | TSESTree.TSUndefinedKeyword, + name = stringifyTypeName(typeNode, context.getSourceCode()), ): void { - const name = stringifyTypeName(typeNode, context.getSourceCode()); + const bannedType = bannedTypes.get(name); - if (name in bannedTypes) { - const bannedType = bannedTypes[name]; + if (bannedType !== undefined) { const customMessage = getCustomMessage(bannedType); const fixWith = bannedType && typeof bannedType === 'object' && bannedType.fixWith; @@ -144,6 +151,18 @@ export default util.createRule({ } return { + ...(bannedTypes.has('null') && { + TSNullKeyword(node): void { + checkBannedTypes(node, 'null'); + }, + }), + + ...(bannedTypes.has('undefined') && { + TSUndefinedKeyword(node): void { + checkBannedTypes(node, 'undefined'); + }, + }), + TSTypeLiteral(node): void { if (node.members.length) { return; diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index bbf2ab29db48..aad95c06e4d9 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -24,6 +24,25 @@ const options: InferOptionsTypeFromRule = [ }, ]; +const options2: InferOptionsTypeFromRule = [ + { + types: { + null: { + message: 'Use undefined instead.', + fixWith: 'undefined', + }, + }, + }, +]; + +const options3: InferOptionsTypeFromRule = [ + { + types: { + undefined: null, + }, + }, +]; + ruleTester.run('ban-types', rule, { valid: [ 'let f = Object();', // Should not fail if there is no options set @@ -53,6 +72,14 @@ ruleTester.run('ban-types', rule, { code: 'let a: NS.Bad._', options, }, + { + code: 'let a: undefined', + options: options2, + }, + { + code: 'let a: null', + options: options3, + }, ], invalid: [ { @@ -70,6 +97,30 @@ ruleTester.run('ban-types', rule, { ], options, }, + { + code: 'let a: undefined;', + errors: [ + { + messageId: 'bannedTypeMessage', + data: { name: 'undefined', customMessage: '' }, + line: 1, + column: 8, + }, + ], + options: options3, + }, + { + code: 'let a: null;', + errors: [ + { + messageId: 'bannedTypeMessage', + data: { name: 'null', customMessage: ' Use undefined instead.' }, + line: 1, + column: 8, + }, + ], + options: options2, + }, { code: 'let aa: Foo;', errors: [ From db4b530f3f049267d679e89d9e75acfcb86faaf2 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 12 Feb 2020 03:29:55 +0100 Subject: [PATCH 2/3] feat(eslint-plugin): [strict-boolean-expressions] refactor, add clearer error messages (#1480) --- .cspell.json | 1 + .../src/rules/strict-boolean-expressions.ts | 346 ++++++++++++---- .../rules/strict-boolean-expressions.test.ts | 381 ++++++++++++------ 3 files changed, 517 insertions(+), 211 deletions(-) diff --git a/.cspell.json b/.cspell.json index 4931ff3a5d97..33f7b70c5f2b 100644 --- a/.cspell.json +++ b/.cspell.json @@ -69,6 +69,7 @@ "pluggable", "postprocess", "prettier's", + "recurse", "reimplement", "resync", "ruleset", diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index c924045ba028..265bc05a41f8 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -6,13 +6,6 @@ import * as ts from 'typescript'; import * as tsutils from 'tsutils'; import * as util from '../util'; -type ExpressionWithTest = - | TSESTree.ConditionalExpression - | TSESTree.DoWhileStatement - | TSESTree.ForStatement - | TSESTree.IfStatement - | TSESTree.WhileStatement; - type Options = [ { ignoreRhs?: boolean; @@ -21,7 +14,19 @@ type Options = [ }, ]; -export default util.createRule({ +type MessageId = + | 'conditionErrorOther' + | 'conditionErrorAny' + | 'conditionErrorNullish' + | 'conditionErrorNullableBoolean' + | 'conditionErrorString' + | 'conditionErrorNullableString' + | 'conditionErrorNumber' + | 'conditionErrorNullableNumber' + | 'conditionErrorObject' + | 'conditionErrorNullableObject'; + +export default util.createRule({ name: 'strict-boolean-expressions', meta: { type: 'suggestion', @@ -49,7 +54,36 @@ export default util.createRule({ }, ], messages: { - strictBooleanExpression: 'Unexpected non-boolean in conditional.', + conditionErrorOther: + 'Unexpected value in conditional. ' + + 'A boolean expression is required.', + conditionErrorAny: + 'Unexpected any value in conditional. ' + + 'An explicit comparison or type cast is required.', + conditionErrorNullish: + 'Unexpected nullish value in conditional. ' + + 'The condition is always false.', + conditionErrorNullableBoolean: + 'Unexpected nullable boolean value in conditional. ' + + 'Please handle the nullish case explicitly.', + conditionErrorString: + 'Unexpected string value in conditional. ' + + 'An explicit empty string check is required.', + conditionErrorNullableString: + 'Unexpected nullable string value in conditional. ' + + 'Please handle the nullish/empty cases explicitly.', + conditionErrorNumber: + 'Unexpected number value in conditional. ' + + 'An explicit zero/NaN check is required.', + conditionErrorNullableNumber: + 'Unexpected nullable number value in conditional. ' + + 'Please handle the nullish/zero/NaN cases explicitly.', + conditionErrorObject: + 'Unexpected object value in conditional. ' + + 'The condition is always true.', + conditionErrorNullableObject: + 'Unexpected nullable object value in conditional. ' + + 'An explicit null check is required.', }, }, defaultOptions: [ @@ -63,109 +97,247 @@ export default util.createRule({ const service = util.getParserServices(context); const checker = service.program.getTypeChecker(); + const checkedNodes = new Set(); + + return { + ConditionalExpression: checkTestExpression, + DoWhileStatement: checkTestExpression, + ForStatement: checkTestExpression, + IfStatement: checkTestExpression, + WhileStatement: checkTestExpression, + 'LogicalExpression[operator!="??"]': checkNode, + 'UnaryExpression[operator="!"]': checkUnaryLogicalExpression, + }; + + type ExpressionWithTest = + | TSESTree.ConditionalExpression + | TSESTree.DoWhileStatement + | TSESTree.ForStatement + | TSESTree.IfStatement + | TSESTree.WhileStatement; + + function checkTestExpression(node: ExpressionWithTest): void { + if (node.test == null) { + return; + } + checkNode(node.test, true); + } + + function checkUnaryLogicalExpression(node: TSESTree.UnaryExpression): void { + checkNode(node.argument, true); + } + /** - * Determines if the node is safe for boolean type + * This function analyzes the type of a boolean expression node and checks if it is allowed. + * It can recurse when checking nested logical operators, so that only the outermost expressions are reported. + * @param node The AST node to check. + * @param isRoot Whether it is the root of a logical expression and there was no recursion yet. + * @returns `true` if there was an error reported. */ - function isValidBooleanNode(node: TSESTree.Expression): boolean { - const tsNode = service.esTreeNodeToTSNodeMap.get(node); - const type = util.getConstrainedTypeAtLocation(checker, tsNode); - - if (tsutils.isTypeFlagSet(type, ts.TypeFlags.BooleanLike)) { - return true; + function checkNode(node: TSESTree.Node, isRoot = false): boolean { + // prevent checking the same node multiple times + if (checkedNodes.has(node)) { + return false; } + checkedNodes.add(node); - // Check variants of union - if (tsutils.isTypeFlagSet(type, ts.TypeFlags.Union)) { - let hasBoolean = false; - for (const ty of (type as ts.UnionType).types) { - if (tsutils.isTypeFlagSet(ty, ts.TypeFlags.BooleanLike)) { - hasBoolean = true; - continue; + // for logical operator, we also check its operands + if ( + node.type === AST_NODE_TYPES.LogicalExpression && + node.operator !== '??' + ) { + let hasError = false; + if (checkNode(node.left)) { + hasError = true; + } + if (!options.ignoreRhs) { + if (checkNode(node.right)) { + hasError = true; } - - if ( - tsutils.isTypeFlagSet(ty, ts.TypeFlags.Null) || - tsutils.isTypeFlagSet(ty, ts.TypeFlags.Undefined) - ) { - if (!options.allowNullable) { - return false; - } - continue; + } + // if this logical operator is not the root of a logical expression + // we only check its operands and return + if (!isRoot) { + return hasError; + } + // if this is the root of a logical expression + // we want to check its resulting type too + else { + // ...unless there already was an error, we exit so we don't double-report + if (hasError) { + return true; } + } + } - if ( - !tsutils.isTypeFlagSet(ty, ts.TypeFlags.StringLike) && - !tsutils.isTypeFlagSet(ty, ts.TypeFlags.NumberLike) - ) { - if (options.allowSafe) { - hasBoolean = true; - continue; - } - } + const tsNode = service.esTreeNodeToTSNodeMap.get(node); + const type = util.getConstrainedTypeAtLocation(checker, tsNode); + let messageId: MessageId | undefined; + + const types = inspectVariantTypes(tsutils.unionTypeParts(type)); - return false; + const is = (...wantedTypes: readonly VariantType[]): boolean => + types.size === wantedTypes.length && + wantedTypes.every(type => types.has(type)); + + // boolean + if (is('boolean')) { + // boolean is always okay + return false; + } + // never + if (is('never')) { + // never is always okay + return false; + } + // nullish + else if (is('nullish')) { + // condition is always false + messageId = 'conditionErrorNullish'; + } + // nullable boolean + else if (is('nullish', 'boolean')) { + if (!options.allowNullable) { + messageId = 'conditionErrorNullableBoolean'; + } + } + // string + else if (is('string')) { + messageId = 'conditionErrorString'; + } + // nullable string + else if (is('nullish', 'string')) { + messageId = 'conditionErrorNullableString'; + } + // number + else if (is('number')) { + messageId = 'conditionErrorNumber'; + } + // nullable number + else if (is('nullish', 'number')) { + messageId = 'conditionErrorNullableNumber'; + } + // object + else if (is('object')) { + // condition is always true + if (!options.allowSafe) { + messageId = 'conditionErrorObject'; + } + } + // nullable object + else if (is('nullish', 'object')) { + if (!options.allowSafe || !options.allowNullable) { + messageId = 'conditionErrorNullableObject'; } - return hasBoolean; + } + // boolean/object + else if (is('boolean', 'object')) { + if (!options.allowSafe) { + messageId = 'conditionErrorOther'; + } + } + // nullable boolean/object + else if (is('nullish', 'boolean', 'object')) { + if (!options.allowSafe || !options.allowNullable) { + messageId = 'conditionErrorOther'; + } + } + // any + else if (is('any')) { + messageId = 'conditionErrorAny'; + } + // other + else { + messageId = 'conditionErrorOther'; + } + + if (messageId != null) { + context.report({ node, messageId }); + return true; } return false; } + /** The types we care about */ + type VariantType = + | 'nullish' + | 'boolean' + | 'string' + | 'number' + | 'object' + | 'any' + | 'never'; + /** - * Asserts that a testable expression contains a boolean, reports otherwise. - * Filters all LogicalExpressions to prevent some duplicate reports. + * Check union variants for the types we care about */ - function assertTestExpressionContainsBoolean( - node: ExpressionWithTest, - ): void { + function inspectVariantTypes(types: ts.Type[]): Set { + const variantTypes = new Set(); + if ( - node.test !== null && - node.test.type !== AST_NODE_TYPES.LogicalExpression && - !isValidBooleanNode(node.test) + types.some(type => + tsutils.isTypeFlagSet( + type, + ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike, + ), + ) ) { - reportNode(node.test); + variantTypes.add('nullish'); } - } - /** - * Asserts that a logical expression contains a boolean, reports otherwise. - */ - function assertLocalExpressionContainsBoolean( - node: TSESTree.LogicalExpression, - ): void { if ( - !isValidBooleanNode(node.left) || - (!options.ignoreRhs && !isValidBooleanNode(node.right)) + types.some(type => + tsutils.isTypeFlagSet(type, ts.TypeFlags.BooleanLike), + ) ) { - reportNode(node); + variantTypes.add('boolean'); } - } - /** - * Asserts that a unary expression contains a boolean, reports otherwise. - */ - function assertUnaryExpressionContainsBoolean( - node: TSESTree.UnaryExpression, - ): void { - if (!isValidBooleanNode(node.argument)) { - reportNode(node.argument); + if ( + types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.StringLike)) + ) { + variantTypes.add('string'); } - } - /** - * Reports an offending node in context. - */ - function reportNode(node: TSESTree.Node): void { - context.report({ node, messageId: 'strictBooleanExpression' }); - } + if ( + types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.NumberLike)) + ) { + variantTypes.add('number'); + } - return { - ConditionalExpression: assertTestExpressionContainsBoolean, - DoWhileStatement: assertTestExpressionContainsBoolean, - ForStatement: assertTestExpressionContainsBoolean, - IfStatement: assertTestExpressionContainsBoolean, - WhileStatement: assertTestExpressionContainsBoolean, - 'LogicalExpression[operator!="??"]': assertLocalExpressionContainsBoolean, - 'UnaryExpression[operator="!"]': assertUnaryExpressionContainsBoolean, - }; + if ( + types.some( + type => + !tsutils.isTypeFlagSet( + type, + ts.TypeFlags.Null | + ts.TypeFlags.Undefined | + ts.TypeFlags.VoidLike | + ts.TypeFlags.BooleanLike | + ts.TypeFlags.StringLike | + ts.TypeFlags.NumberLike | + ts.TypeFlags.Any | + ts.TypeFlags.Unknown | + ts.TypeFlags.Never, + ), + ) + ) { + variantTypes.add('object'); + } + + if ( + types.some(type => + tsutils.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown), + ) + ) { + variantTypes.add('any'); + } + + if (types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.Never))) { + variantTypes.add('never'); + } + + return variantTypes; + } }, }); diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index cf6dbd5cd361..d3d5700c5a7b 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -1,5 +1,9 @@ import rule from '../../src/rules/strict-boolean-expressions'; -import { RuleTester, getFixturesRootDir } from '../RuleTester'; +import { + RuleTester, + getFixturesRootDir, + batchedSingleLineTests, +} from '../RuleTester'; const rootPath = getFixturesRootDir(); @@ -158,13 +162,13 @@ ruleTester.run('strict-boolean-expressions', rule, { { options: [{ ignoreRhs: true }], code: ` - const obj = {}; + const obj = { x: 1 }; const bool = false; const boolOrObj = bool || obj; const boolAndObj = bool && obj; `, }, - { + ...batchedSingleLineTests({ options: [{ allowNullable: true }], code: ` const f1 = (x?: boolean) => x ? 1 : 0; @@ -172,51 +176,59 @@ ruleTester.run('strict-boolean-expressions', rule, { const f3 = (x?: true | null) => x ? 1 : 0; const f4 = (x?: false) => x ? 1 : 0; `, - }, + }), ` declare const x: string | null; y = x ?? 'foo'; `, - { + ...batchedSingleLineTests({ options: [{ allowSafe: true }], code: ` - type TestType = { a: string; }; - const f1 = (x: boolean | TestType) => x ? 1 : 0; - const f2 = (x: true | TestType) => x ? 1 : 0; - const f3 = (x: TestType | false) => x ? 1 : 0; + const f1 = (x: boolean | { a: string }) => x ? 1 : 0; + const f2 = (x: true | { a: string }) => x ? 1 : 0; + const f3 = (x: { a: string } | false) => x ? 1 : 0; `, - }, - { + }), + ...batchedSingleLineTests({ options: [{ allowNullable: true, allowSafe: true }], code: ` - type TestType = { a: string; }; - type TestType2 = { b: number; }; - const f1 = (x?: boolean | TestType) => x ? 1 : 0; - const f2 = (x: TestType | TestType2 | null) => x ? 1 : 0; - const f3 = (x?: TestType | TestType2 | null) => x ? 1 : 0; - const f4 = (x?: TestType2 | true) => x ? 1 : 0; + const f1 = (x?: boolean | { a?: 1 }) => x ? 1 : 0; + const f2 = (x: { a?: 1 } | { b?: "a" } | null) => x ? 1 : 0; + const f3 = (x?: { a?: 1 } | { b?: "a" } | null) => x ? 1 : 0; + const f4 = (x?: { b?: "a" } | true) => x ? 1 : 0; const f5 = (g?: (x: number) => number) => g ? g(1) : 0; `, - }, - { + }), + ...batchedSingleLineTests({ options: [{ allowNullable: true, allowSafe: true, ignoreRhs: true }], code: ` - type TestType = { foo? : { bar?: string; }; }; - const f1 = (x?: TestType) => x && x.foo && x.foo.bar + const f1 = (x?: { a: null }) => x && x.foo && x.foo.bar const f2 = (g?: (x: number) => number) => g && g(1) `, - }, + }), + ` + declare let x: never; + if (x) {} + `, + ...batchedSingleLineTests({ + code: ` + function f1(x: never) { return !x } + function f2(x: never) { return x ? 1 : 0 } + function f3(x: never, y: never) { return x && y } + function f5(x: never | boolean) { if (!x) {} } + `, + }), ], invalid: [ { code: ` - let val = 1; + let val = "foo"; let bool = !val; `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorString', line: 3, column: 21, }, @@ -229,7 +241,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 3, column: 21, }, @@ -242,9 +254,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 3, - column: 20, + column: 28, }, ], }, @@ -255,9 +267,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 3, - column: 20, + column: 28, }, ], }, @@ -268,9 +280,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 3, - column: 20, + column: 28, }, ], }, @@ -281,9 +293,34 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorAny', line: 3, - column: 20, + column: 28, + }, + ], + }, + { + code: ` + let num = 1; + let str = "foo" + let val = null; + let bool = true && (val || num || str); + `, + errors: [ + { + messageId: 'conditionErrorNullish', + line: 5, + column: 29, + }, + { + messageId: 'conditionErrorNumber', + line: 5, + column: 36, + }, + { + messageId: 'conditionErrorString', + line: 5, + column: 43, }, ], }, @@ -295,7 +332,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 2, column: 13, }, @@ -309,7 +346,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 2, column: 13, }, @@ -317,14 +354,14 @@ ruleTester.run('strict-boolean-expressions', rule, { }, { code: ` - let item = 1; + let item = "foo"; if (item) { return; } `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorString', line: 3, column: 13, }, @@ -339,7 +376,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 3, column: 13, }, @@ -355,9 +392,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, - column: 13, + column: 22, }, ], }, @@ -371,7 +408,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 13, }, @@ -387,7 +424,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 13, }, @@ -403,9 +440,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, - column: 13, + column: 22, }, ], }, @@ -419,7 +456,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 13, }, @@ -435,7 +472,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 13, }, @@ -443,11 +480,11 @@ ruleTester.run('strict-boolean-expressions', rule, { }, { code: ` - const bool = 1 ? true : false; + const bool = "foo" ? true : false; `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorString', line: 2, column: 22, }, @@ -459,7 +496,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 2, column: 22, }, @@ -472,7 +509,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 3, column: 22, }, @@ -485,7 +522,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 3, column: 22, }, @@ -499,7 +536,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 22, }, @@ -513,9 +550,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, - column: 22, + column: 31, }, ], }, @@ -527,9 +564,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, - column: 22, + column: 31, }, ], }, @@ -541,7 +578,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 22, }, @@ -555,9 +592,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, - column: 22, + column: 31, }, ], }, @@ -569,9 +606,9 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, - column: 22, + column: 31, }, ], }, @@ -583,7 +620,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 2, column: 25, }, @@ -597,7 +634,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 2, column: 25, }, @@ -612,7 +649,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 3, column: 25, }, @@ -627,7 +664,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 3, column: 25, }, @@ -635,7 +672,7 @@ ruleTester.run('strict-boolean-expressions', rule, { }, { code: ` - let bool1 = 1; + let bool1 = "foo"; let bool2 = true; for (let i = 0; bool1 && bool2; i++) { return; @@ -643,7 +680,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorString', line: 4, column: 25, }, @@ -659,7 +696,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 25, }, @@ -675,7 +712,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 25, }, @@ -691,7 +728,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 25, }, @@ -705,7 +742,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 2, column: 16, }, @@ -719,7 +756,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 2, column: 16, }, @@ -734,7 +771,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 3, column: 16, }, @@ -749,7 +786,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 3, column: 16, }, @@ -765,7 +802,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 16, }, @@ -781,7 +818,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 16, }, @@ -797,7 +834,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 4, column: 16, }, @@ -813,7 +850,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 16, }, @@ -823,11 +860,11 @@ ruleTester.run('strict-boolean-expressions', rule, { code: ` do { return; - } while (1); + } while ("foo"); `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorString', line: 4, column: 18, }, @@ -841,7 +878,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 4, column: 18, }, @@ -856,7 +893,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 5, column: 18, }, @@ -871,7 +908,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorAny', line: 5, column: 18, }, @@ -887,7 +924,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 6, column: 18, }, @@ -903,7 +940,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorAny', line: 6, column: 18, }, @@ -919,7 +956,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 6, column: 18, }, @@ -935,7 +972,7 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorAny', line: 6, column: 18, }, @@ -947,26 +984,26 @@ ruleTester.run('strict-boolean-expressions', rule, { `, errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 2, column: 58, }, ], }, - { + ...batchedSingleLineTests({ errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullableBoolean', line: 2, - column: 55, + column: 47, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullableBoolean', line: 3, column: 37, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 4, column: 41, }, @@ -976,83 +1013,155 @@ ruleTester.run('strict-boolean-expressions', rule, { const f2 = (x?: boolean) => x ? 1 : 0; const f3 = (x: boolean | {}) => x ? 1 : 0; `, + }), + { + options: [{ ignoreRhs: true }], + errors: [ + { + messageId: 'conditionErrorObject', + line: 4, + column: 27, + }, + { + messageId: 'conditionErrorObject', + line: 5, + column: 28, + }, + ], + code: ` + const obj = { x: 1 }; + const bool = false; + const objOrBool = obj || bool; + const objAndBool = obj && bool; + `, }, { options: [{ ignoreRhs: true }], errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 4, - column: 19, + column: 13, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 5, - column: 20, + column: 13, }, ], code: ` -const obj = {}; -const bool = false; -const objOrBool = obj || bool; -const objAndBool = obj && bool; -`, + const condition = () => false; + const obj = { x: 1 }; + if (condition() || obj) {} + if (condition() && obj) {} + `, }, { + options: [{ ignoreRhs: true }], + errors: [ + { + messageId: 'conditionErrorOther', + line: 4, + column: 13, + }, + { + messageId: 'conditionErrorOther', + line: 5, + column: 13, + }, + ], + code: ` + declare let condition: boolean; + const obj = { x: 1 }; + if (condition || obj) {} + if (condition && obj) {} + `, + }, + ...batchedSingleLineTests({ options: [{ allowNullable: true }], errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullish', line: 2, - column: 44, + column: 37, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNullableNumber', line: 3, - column: 35, + column: 36, + }, + { + messageId: 'conditionErrorNullableString', + line: 4, + column: 36, + }, + { + messageId: 'conditionErrorOther', + line: 5, + column: 45, }, ], code: ` - const f = (x: null | undefined) => x ? 1 : 0; - const f = (x?: number) => x ? 1 : 0; + const f1 = (x: null | undefined) => x ? 1 : 0; + const f2 = (x?: number) => x ? 1 : 0; + const f3 = (x?: string) => x ? 1 : 0; + const f4 = (x?: string | number) => x ? 1 : 0; `, - }, + }), { - options: [{ allowSafe: true }], errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 3, - column: 42, + column: 43, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 4, - column: 42, + column: 44, + }, + ], + code: ` + type Type = { a: string; }; + const f1 = (x: Type | boolean) => x ? 1 : 0; + const f2 = (x?: Type | boolean) => x ? 1 : 0; + `, + }, + ...batchedSingleLineTests({ + options: [{ allowSafe: true }], + errors: [ + { + messageId: 'conditionErrorOther', + line: 2, + column: 36, }, { - messageId: 'strictBooleanExpression', - line: 5, + messageId: 'conditionErrorOther', + line: 3, + column: 44, + }, + { + messageId: 'conditionErrorOther', + line: 4, column: 44, }, ], code: ` - type Type = { a: string; }; - const f1 = (x: Type | string) => x ? 1 : 0; - const f2 = (x: Type | number) => x ? 1 : 0; + const f1 = (x: object | string) => x ? 1 : 0; + const f2 = (x: object | number) => x ? 1 : 0; const f3 = (x: number | string) => x ? 1 : 0; `, - }, + }), { options: [{ allowSafe: true }], errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorNumber', line: 8, column: 34, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorString', line: 9, column: 34, }, @@ -1072,12 +1181,12 @@ const objAndBool = obj && bool; options: [{ allowNullable: true, allowSafe: true }], errors: [ { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 3, column: 43, }, { - messageId: 'strictBooleanExpression', + messageId: 'conditionErrorOther', line: 4, column: 49, }, @@ -1088,5 +1197,29 @@ const objAndBool = obj && bool; const f2 = (x: Type | number | null) => x ? 1 : 0; `, }, + ...batchedSingleLineTests({ + errors: [ + { + messageId: 'conditionErrorObject', + line: 2, + column: 31, + }, + { + messageId: 'conditionErrorNullableObject', + line: 3, + column: 40, + }, + { + messageId: 'conditionErrorNullableObject', + line: 4, + column: 47, + }, + ], + code: ` + const f1 = (x: { x: any }) => x ? 1 : 0; + const f2 = (x?: { x: any }) => x ? 1 : 0; + const f3 = (x?: { x: any } | null) => x ? 1 : 0; + `, + }), ], }); From f9dd7ec3b4589bc283b596e045ca50a3f5475242 Mon Sep 17 00:00:00 2001 From: James Henry Date: Mon, 17 Feb 2020 18:01:51 +0000 Subject: [PATCH 3/3] chore: publish v2.20.0 --- CHANGELOG.md | 12 ++++++++++++ lerna.json | 2 +- packages/eslint-plugin-internal/CHANGELOG.md | 8 ++++++++ packages/eslint-plugin-internal/package.json | 4 ++-- packages/eslint-plugin-tslint/CHANGELOG.md | 8 ++++++++ packages/eslint-plugin-tslint/package.json | 6 +++--- packages/eslint-plugin/CHANGELOG.md | 12 ++++++++++++ packages/eslint-plugin/package.json | 4 ++-- packages/experimental-utils/CHANGELOG.md | 8 ++++++++ packages/experimental-utils/package.json | 4 ++-- packages/parser/CHANGELOG.md | 8 ++++++++ packages/parser/package.json | 8 ++++---- packages/shared-fixtures/CHANGELOG.md | 8 ++++++++ packages/shared-fixtures/package.json | 2 +- packages/typescript-estree/CHANGELOG.md | 8 ++++++++ packages/typescript-estree/package.json | 4 ++-- 16 files changed, 89 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87197038aba8..db2020835213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + + +### Features + +* **eslint-plugin:** [ban-types] allow banning null and undefined ([#821](https://github.com/typescript-eslint/typescript-eslint/issues/821)) ([0b2b887](https://github.com/typescript-eslint/typescript-eslint/commit/0b2b887c06f2582d812a45f7a8deb82f52d82a84)) +* **eslint-plugin:** [strict-boolean-expressions] refactor, add clearer error messages ([#1480](https://github.com/typescript-eslint/typescript-eslint/issues/1480)) ([db4b530](https://github.com/typescript-eslint/typescript-eslint/commit/db4b530f3f049267d679e89d9e75acfcb86faaf2)) + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/typescript-eslint diff --git a/lerna.json b/lerna.json index 679029c77f30..b4c62e5e783f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.19.2", + "version": "2.20.0", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 3cedd8fb87f6..a9f9f05b7c11 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 2e90dc34e2b6..29967952fa04 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "2.19.2", + "version": "2.20.0", "private": true, "main": "dist/index.js", "scripts": { @@ -12,6 +12,6 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.19.2" + "@typescript-eslint/experimental-utils": "2.20.0" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index 280dc082e9a5..bf7070f5ee6a 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index 8ebc668fc7e5..553be2e38d48 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "2.19.2", + "version": "2.20.0", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -31,7 +31,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.19.2", + "@typescript-eslint/experimental-utils": "2.20.0", "lodash": "^4.17.15" }, "peerDependencies": { @@ -41,6 +41,6 @@ }, "devDependencies": { "@types/lodash": "^4.14.149", - "@typescript-eslint/parser": "2.19.2" + "@typescript-eslint/parser": "2.20.0" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index f1e43669b4d4..fd4a172bfd6b 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + + +### Features + +* **eslint-plugin:** [ban-types] allow banning null and undefined ([#821](https://github.com/typescript-eslint/typescript-eslint/issues/821)) ([0b2b887](https://github.com/typescript-eslint/typescript-eslint/commit/0b2b887c06f2582d812a45f7a8deb82f52d82a84)) +* **eslint-plugin:** [strict-boolean-expressions] refactor, add clearer error messages ([#1480](https://github.com/typescript-eslint/typescript-eslint/issues/1480)) ([db4b530](https://github.com/typescript-eslint/typescript-eslint/commit/db4b530f3f049267d679e89d9e75acfcb86faaf2)) + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/eslint-plugin diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 28679c429f3b..098f3b39588c 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "2.19.2", + "version": "2.20.0", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -41,7 +41,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.19.2", + "@typescript-eslint/experimental-utils": "2.20.0", "eslint-utils": "^1.4.3", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index b3e7648fd2c9..e85cdffc4b2c 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/experimental-utils diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 63e6e8b459ce..31eccbf1f64f 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "2.19.2", + "version": "2.20.0", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -37,7 +37,7 @@ }, "dependencies": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.19.2", + "@typescript-eslint/typescript-estree": "2.20.0", "eslint-scope": "^5.0.0" }, "peerDependencies": { diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index faee2107a25c..0a89b836d18a 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index 6fbd0ebf45a4..17ac2bae6c0e 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "2.19.2", + "version": "2.20.0", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/parser.js", "types": "dist/parser.d.ts", @@ -43,13 +43,13 @@ }, "dependencies": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.19.2", - "@typescript-eslint/typescript-estree": "2.19.2", + "@typescript-eslint/experimental-utils": "2.20.0", + "@typescript-eslint/typescript-estree": "2.20.0", "eslint-visitor-keys": "^1.1.0" }, "devDependencies": { "@types/glob": "^7.1.1", - "@typescript-eslint/shared-fixtures": "2.19.2", + "@typescript-eslint/shared-fixtures": "2.20.0", "glob": "*" }, "peerDependenciesMeta": { diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index 837db7ef624a..4bc15b28871c 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index dd5f2ffc53de..f955ffcc367f 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "2.19.2", + "version": "2.20.0", "private": true, "scripts": { "build": "tsc -b tsconfig.build.json", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index c0fb10421bb6..bcd32357a487 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.20.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.2...v2.20.0) (2020-02-17) + +**Note:** Version bump only for package @typescript-eslint/typescript-estree + + + + + ## [2.19.2](https://github.com/typescript-eslint/typescript-eslint/compare/v2.19.1...v2.19.2) (2020-02-10) **Note:** Version bump only for package @typescript-eslint/typescript-estree diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 5aa3d0da7071..894aa7565a21 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "2.19.2", + "version": "2.20.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/parser.js", "types": "dist/parser.d.ts", @@ -58,7 +58,7 @@ "@types/lodash": "^4.14.149", "@types/semver": "^6.2.0", "@types/tmp": "^0.1.0", - "@typescript-eslint/shared-fixtures": "2.19.2", + "@typescript-eslint/shared-fixtures": "2.20.0", "tmp": "^0.1.0", "typescript": "*" },