diff --git a/packages/typescript-eslint-parser/package.json b/packages/typescript-eslint-parser/package.json index bc953458e8d6..5606523a74b4 100644 --- a/packages/typescript-eslint-parser/package.json +++ b/packages/typescript-eslint-parser/package.json @@ -41,6 +41,9 @@ "typescript-estree": "18.0.0" }, "devDependencies": { + "@types/eslint": "^4.16.5", + "@types/estree": "^0.0.39", + "@types/eslint-visitor-keys": "^1.0.0", "@typescript-eslint/shared-fixtures": "*" } } diff --git a/packages/typescript-eslint-parser/src/analyze-scope.ts b/packages/typescript-eslint-parser/src/analyze-scope.ts index bc9df6f4e79a..1fd5c553643c 100644 --- a/packages/typescript-eslint-parser/src/analyze-scope.ts +++ b/packages/typescript-eslint-parser/src/analyze-scope.ts @@ -1,4 +1,4 @@ -import escope from 'eslint-scope'; +import { ScopeManager } from 'eslint-scope'; import { Definition, ParameterDefinition } from 'eslint-scope/lib/definition'; import OriginalPatternVisitor from 'eslint-scope/lib/pattern-visitor'; import Reference from 'eslint-scope/lib/reference'; @@ -7,6 +7,11 @@ import { Scope } from 'eslint-scope/lib/scope'; import { getKeys as fallback } from 'eslint-visitor-keys'; import { ParserOptions } from './parser-options'; import { visitorKeys as childVisitorKeys } from './visitor-keys'; +import { + PatternVisitorCallback, + PatternVisitorOptions +} from 'eslint-scope/lib/options'; +import { Node } from 'estree'; /** * Define the override function of `Scope#__define` for global augmentation. @@ -27,14 +32,23 @@ function overrideDefine(define: any) { /** The scope class for enum. */ class EnumScope extends Scope { - constructor(scopeManager: any, upperScope: any, block: any) { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ) { + // @ts-ignore super(scopeManager, 'enum', upperScope, block, false); } } class PatternVisitor extends OriginalPatternVisitor { - constructor(...args: any[]) { - super(...args); + constructor( + options: PatternVisitorOptions, + rootPattern: any, + callback: PatternVisitorCallback + ) { + super(options, rootPattern, callback); } Identifier(node: any) { @@ -76,8 +90,10 @@ class PatternVisitor extends OriginalPatternVisitor { } class Referencer extends OriginalReferencer { - constructor(...args: any[]) { - super(...args); + protected typeMode: boolean; + + constructor(options: any, scopeManager: ScopeManager) { + super(options, scopeManager); this.typeMode = false; } @@ -88,7 +104,11 @@ class Referencer extends OriginalReferencer { * @param {Function} callback The callback function for left-hand side nodes. * @returns {void} */ - visitPattern(node: any, options: any, callback: any) { + visitPattern( + node: any, + options: PatternVisitorOptions, + callback: PatternVisitorCallback + ) { if (!node) { return; } @@ -102,6 +122,7 @@ class Referencer extends OriginalReferencer { visitor.visit(node); if (options.processRightHandNodes) { + // @ts-ignore visitor.rightHandNodes.forEach(this.visit, this); } } @@ -125,11 +146,12 @@ class Referencer extends OriginalReferencer { ); // Remove overload definition to avoid confusion of no-redeclare rule. - const { defs, identifiers } = upperScope.set.get(id.name); + const { defs, identifiers } = upperScope.set.get(id.name)!; for (let i = 0; i < defs.length; ++i) { const def = defs[i]; if ( def.type === 'FunctionName' && + // @ts-ignore def.node.type === 'TSDeclareFunction' ) { defs.splice(i, 1); @@ -153,7 +175,7 @@ class Referencer extends OriginalReferencer { this.visitPattern( params[i], { processRightHandNodes: true }, - (pattern: any, info: any) => { + (pattern, info) => { innerScope.__define( pattern, new ParameterDefinition(pattern, node, i, info.rest) @@ -305,7 +327,7 @@ class Referencer extends OriginalReferencer { if (id) { const variable = scope.set.get(id.name); const defs = variable && variable.defs; - const existed = defs && defs.some((d: any) => d.type === 'FunctionName'); + const existed = defs && defs.some(d => d.type === 'FunctionName'); if (!existed) { scope.__define( id, @@ -743,7 +765,7 @@ class Referencer extends OriginalReferencer { * @param {Decorator[]|undefined} decorators The decorator nodes to visit. * @returns {void} */ - visitDecorators(decorators: any[] | undefined) { + visitDecorators(decorators?: any[]) { if (decorators) { decorators.forEach(this.visit, this); } @@ -781,7 +803,7 @@ export function analyzeScope(ast: any, parserOptions: ParserOptions) { fallback }; - const scopeManager = new escope.ScopeManager(options); + const scopeManager = new ScopeManager(options); const referencer = new Referencer(options, scopeManager); referencer.visit(ast); diff --git a/packages/typescript-eslint-parser/src/typings.d.ts b/packages/typescript-eslint-parser/src/typings.d.ts index 1dbc8b41a65c..08f92526c823 100644 --- a/packages/typescript-eslint-parser/src/typings.d.ts +++ b/packages/typescript-eslint-parser/src/typings.d.ts @@ -1,12 +1,498 @@ -declare module 'eslint-scope'; -declare module 'eslint-scope/lib/definition'; -declare module 'eslint-scope/lib/pattern-visitor'; -declare module 'eslint-scope/lib/reference'; -declare module 'eslint-scope/lib/referencer'; -declare module 'eslint-scope/lib/scope'; +// Type definitions for eslint-scope 4.0.0 +// Project: http://github.com/eslint/eslint-scope +// Definitions by: Armano +declare module 'eslint-scope/lib/options' { + export type PatternVisitorCallback = (pattern: any, info: any) => void; -declare module 'eslint'; + export interface PatternVisitorOptions { + processRightHandNodes?: boolean; + } -declare module 'eslint-visitor-keys'; + export abstract class Visitor { + visitChildren(node: Node): void; + visit(node: Node): void; + } +} + +declare module 'eslint-scope/lib/variable' { + import * as eslint from 'eslint'; + import { Identifier } from 'estree'; + import Reference from 'eslint-scope/lib/reference'; + + class Variable implements eslint.Scope.Variable { + name: string; + identifiers: Identifier[]; + references: Reference[]; + defs: eslint.Scope.Definition[]; + } + export default Variable; +} + +declare module 'eslint-scope/lib/definition' { + import { Identifier, Node } from 'estree'; + + class Definition { + type: string; + name: Identifier; + node: Node; + parent?: Node | null; + index?: number | null; + kind?: string | null; + + constructor( + type: string, + name: Identifier, + node: Node, + parent?: Node | null, + index?: number | null, + kind?: string | null + ); + } + + class ParameterDefinition extends Definition { + rest?: boolean; + + constructor( + name: Identifier, + node: Node, + index?: number | null, + rest?: boolean + ); + } + + export { ParameterDefinition, Definition }; +} + +declare module 'eslint-scope/lib/pattern-visitor' { + import ScopeManager from 'eslint-scope/lib/scope-manager'; + import { Node } from 'estree'; + import { + PatternVisitorCallback, + PatternVisitorOptions, + Visitor + } from 'eslint-scope/lib/options'; + + class PatternVisitor extends Visitor { + protected options: any; + protected scopeManager: ScopeManager; + protected parent?: Node; + public rightHandNodes: Node[]; + + static isPattern(node: Node): boolean; + + constructor( + options: PatternVisitorOptions, + rootPattern: any, + callback: PatternVisitorCallback + ); + + Identifier(pattern: Node): void; + Property(property: Node): void; + ArrayPattern(pattern: Node): void; + AssignmentPattern(pattern: Node): void; + RestElement(pattern: Node): void; + MemberExpression(node: Node): void; + SpreadElement(node: Node): void; + ArrayExpression(node: Node): void; + AssignmentExpression(node: Node): void; + CallExpression(node: Node): void; + } + + export default PatternVisitor; +} + +declare module 'eslint-scope/lib/referencer' { + import { Scope } from 'eslint-scope/lib/scope'; + import ScopeManager from 'eslint-scope/lib/scope-manager'; + import { Node } from 'estree'; + import { + PatternVisitorCallback, + PatternVisitorOptions, + Visitor + } from 'eslint-scope/lib/options'; + + class Referencer extends Visitor { + protected isInnerMethodDefinition: boolean; + protected options: any; + protected scopeManager: ScopeManager; + protected parent?: Node; + + constructor(options: any, scopeManager: ScopeManager); + + currentScope(): Scope; + close(node: Node): void; + pushInnerMethodDefinition(isInnerMethodDefinition: boolean): boolean; + popInnerMethodDefinition(isInnerMethodDefinition: boolean): void; + + referencingDefaultValue( + pattern: any, + assignments: any, + maybeImplicitGlobal: any, + init: boolean + ): void; + visitPattern( + node: Node, + options: PatternVisitorOptions, + callback: PatternVisitorCallback + ): void; + visitFunction(node: Node): void; + visitClass(node: Node): void; + visitProperty(node: Node): void; + visitForIn(node: Node): void; + visitVariableDeclaration( + variableTargetScope: any, + type: any, + node: Node, + index: any + ): void; + + AssignmentExpression(node: Node): void; + CatchClause(node: Node): void; + Program(node: Node): void; + Identifier(node: Node): void; + UpdateExpression(node: Node): void; + MemberExpression(node: Node): void; + Property(node: Node): void; + MethodDefinition(node: Node): void; + BreakStatement(): void; + ContinueStatement(): void; + LabeledStatement(node: Node): void; + ForStatement(node: Node): void; + ClassExpression(node: Node): void; + ClassDeclaration(node: Node): void; + CallExpression(node: Node): void; + BlockStatement(node: Node): void; + ThisExpression(): void; + WithStatement(node: Node): void; + VariableDeclaration(node: Node): void; + SwitchStatement(node: Node): void; + FunctionDeclaration(node: Node): void; + FunctionExpression(node: Node): void; + ForOfStatement(node: Node): void; + ForInStatement(node: Node): void; + ArrowFunctionExpression(node: Node): void; + ImportDeclaration(node: Node): void; + visitExportDeclaration(node: Node): void; + ExportDeclaration(node: Node): void; + ExportNamedDeclaration(node: Node): void; + ExportSpecifier(node: Node): void; + MetaProperty(): void; + } + + export default Referencer; +} + +declare module 'eslint-scope/lib/scope' { + import * as eslint from 'eslint'; + import { Node } from 'estree'; + import Reference from 'eslint-scope/lib/reference'; + import Variable from 'eslint-scope/lib/variable'; + import ScopeManager from 'eslint-scope/lib/scope-manager'; + import { Definition } from 'eslint-scope/lib/definition'; + + type ScopeType = + | 'block' + | 'catch' + | 'class' + | 'for' + | 'function' + | 'function-expression-name' + | 'global' + | 'module' + | 'switch' + | 'with' + | 'TDZ'; + + class Scope implements eslint.Scope.Scope { + type: ScopeType; + isStrict: boolean; + upper: Scope | null; + childScopes: Scope[]; + variableScope: Scope; + block: Node; + variables: Variable[]; + set: Map; + references: Reference[]; + through: Reference[]; + thisFound?: boolean; + functionExpressionScope: boolean; + + constructor( + scopeManager: ScopeManager, + type: ScopeType, + upperScope: Scope | null, + block: Node | null, + isMethodDefinition: boolean + ); + + __shouldStaticallyClose(scopeManager: ScopeManager): boolean; + __shouldStaticallyCloseForGlobal(ref: any): boolean; + __staticCloseRef(ref: any): void; + __dynamicCloseRef(ref: any): void; + __globalCloseRef(ref: any): void; + __close(scopeManager: ScopeManager): Scope; + __isValidResolution(ref: any, variable: any): boolean; + __resolve(ref: any): boolean; + __delegateToUpperScope(ref: any): void; + __addDeclaredVariablesOfNode(variable: any, node: Node): void; + __defineGeneric( + name: any, + set: any, + variables: any, + node: any, + def: Definition + ): void; + + __define(node: Node, def: Definition): void; + + __referencing( + node: Node, + assign: number, + writeExpr: Node, + maybeImplicitGlobal: any, + partial: any, + init: any + ): void; + + __detectEval(): void; + __detectThis(): void; + __isClosed(): boolean; + /** + * returns resolved {Reference} + * @method Scope#resolve + * @param {Espree.Identifier} ident - identifier to be resolved. + * @returns {Reference} reference + */ + resolve(ident: Node): Reference; + + /** + * returns this scope is static + * @method Scope#isStatic + * @returns {boolean} static + */ + isStatic(): boolean; + + /** + * returns this scope has materialized arguments + * @method Scope#isArgumentsMaterialized + * @returns {boolean} arguemnts materialized + */ + isArgumentsMaterialized(): boolean; + + /** + * returns this scope has materialized `this` reference + * @method Scope#isThisMaterialized + * @returns {boolean} this materialized + */ + isThisMaterialized(): boolean; + + isUsedName(name: any): boolean; + } + + class GlobalScope extends Scope { + constructor(scopeManager: ScopeManager, block: Node | null); + } + + class ModuleScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class FunctionExpressionNameScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class CatchScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class WithScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class BlockScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class SwitchScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class FunctionScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null, + isMethodDefinition: boolean + ); + } + + class ForScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + class ClassScope extends Scope { + constructor( + scopeManager: ScopeManager, + upperScope: Scope, + block: Node | null + ); + } + + export { + Scope, + GlobalScope, + ModuleScope, + FunctionExpressionNameScope, + CatchScope, + WithScope, + BlockScope, + SwitchScope, + FunctionScope, + ForScope, + ClassScope + }; +} + +declare module 'eslint-scope/lib/reference' { + import * as eslint from 'eslint'; + import { Identifier, Node } from 'estree'; + import { Scope } from 'eslint-scope/lib/scope'; + import Variable from 'eslint-scope/lib/variable'; + + class Reference implements eslint.Scope.Reference { + identifier: Identifier; + from: Scope; + resolved: Variable | null; + writeExpr: Node | null; + init: boolean; + + isWrite(): boolean; + isRead(): boolean; + isWriteOnly(): boolean; + isReadOnly(): boolean; + isReadWrite(): boolean; + + static READ: 0x1; + static WRITE: 0x2; + static RW: 0x3; + } + export default Reference; +} + +declare module 'eslint-scope/lib/scope-manager' { + import * as eslint from 'eslint'; + import { Scope } from 'eslint-scope/lib/scope'; + import Variable from 'eslint-scope/lib/variable'; + + interface ScopeManagerOptions { + directive?: boolean; + optimistic?: boolean; + ignoreEval?: boolean; + nodejsScope?: boolean; + sourceType?: 'module' | 'script'; + impliedStrict?: boolean; + ecmaVersion?: number; + } + + class ScopeManager implements eslint.Scope.ScopeManager { + __options: ScopeManagerOptions; + __currentScope: Scope; + scopes: Scope[]; + globalScope: Scope; + + constructor(options: ScopeManagerOptions); + + __useDirective(): boolean; + __isOptimistic(): boolean; + __ignoreEval(): boolean; + __isNodejsScope(): boolean; + isModule(): boolean; + isImpliedStrict(): boolean; + isStrictModeSupported(): boolean; + + // Returns appropriate scope for this node. + __get(node: Node): Scope; + getDeclaredVariables(node: {}): Variable[]; + acquire(node: {}, inner?: boolean): Scope | null; + acquireAll(node: Node): Scope | null; + release(node: Node, inner?: boolean): Scope | null; + attach(): void; + detach(): void; + + __nestScope(scope: Scope): Scope; + __nestGlobalScope(node: Node): Scope; + __nestBlockScope(node: Node): Scope; + __nestFunctionScope(node: Node, isMethodDefinition: boolean): Scope; + __nestForScope(node: Node): Scope; + __nestCatchScope(node: Node): Scope; + __nestWithScope(node: Node): Scope; + __nestClassScope(node: Node): Scope; + __nestSwitchScope(node: Node): Scope; + __nestModuleScope(node: Node): Scope; + __nestFunctionExpressionNameScope(node: Node): Scope; + + __isES6(): boolean; + } + export default ScopeManager; +} + +declare module 'eslint-scope' { + import ScopeManager from 'eslint-scope/lib/scope-manager'; + import Reference from 'eslint-scope/lib/reference'; + import Scope from 'eslint-scope/lib/scope'; + import Variable from 'eslint-scope/lib/variable'; + + interface AnalysisOptions { + optimistic?: boolean; + directive?: boolean; + ignoreEval?: boolean; + nodejsScope?: boolean; + impliedStrict?: boolean; + fallback?: string | ((node: {}) => string[]); + sourceType?: 'script' | 'module'; + ecmaVersion?: number; + } + function analyze(ast: {}, options?: AnalysisOptions): ScopeManager; + + const version: string; + + export { + AnalysisOptions, + version, + Reference, + Variable, + Scope, + ScopeManager, + analyze + }; +} declare module 'eslint/lib/util/traverser'; diff --git a/packages/typescript-eslint-parser/tests/lib/basics.ts b/packages/typescript-eslint-parser/tests/lib/basics.ts index ab446a36f51c..5dc91decaf69 100644 --- a/packages/typescript-eslint-parser/tests/lib/basics.ts +++ b/packages/typescript-eslint-parser/tests/lib/basics.ts @@ -25,7 +25,7 @@ describe('basics', () => { const code = ` export const Price: React.SFC = function Price(props) {} `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { test: 'error' @@ -33,16 +33,20 @@ export const Price: React.SFC = function Price(props) {} }; linter.defineParser('typescript-eslint-parser', parser); - linter.defineRule('test', (context: any) => ({ - TSTypeReference(node: any) { - const name = context.getSourceCode().getText(node.typeName); - context.report({ - node, - message: 'called on {{name}}', - data: { name } - }); + linter.defineRule('test', { + create(context: any) { + return { + TSTypeReference(node: any) { + const name = context.getSourceCode().getText(node.typeName); + context.report({ + node, + message: 'called on {{name}}', + data: { name } + }); + } + }; } - })); + }); const messages = linter.verify(code, config, { filename: 'issue.ts' }); diff --git a/packages/typescript-eslint-parser/tests/lib/scope-analysis.ts b/packages/typescript-eslint-parser/tests/lib/scope-analysis.ts index 5f46bbb2ae05..441b3519b635 100644 --- a/packages/typescript-eslint-parser/tests/lib/scope-analysis.ts +++ b/packages/typescript-eslint-parser/tests/lib/scope-analysis.ts @@ -224,7 +224,7 @@ export type SomeThing = { id: string; } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-undef': 'error' @@ -242,7 +242,7 @@ interface Foo { } const bar = 'blah' `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-use-before-define': 'error' @@ -260,7 +260,7 @@ interface Runnable { toString (): string } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-undef': 'error' @@ -276,7 +276,7 @@ interface Runnable { const Foo = 1; type Foo = 1; `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-redeclare': 'error' @@ -292,7 +292,7 @@ type Foo = 1; type foo = any; function bar(foo: any) {} `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-shadow': 'error' @@ -308,7 +308,7 @@ function bar(foo: any) {} /*globals document, selector */ const links = document.querySelectorAll( selector ) as NodeListOf `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-undef': 'error' @@ -325,7 +325,7 @@ class X { field = {} } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-undef': 'error' @@ -345,7 +345,7 @@ export default class Test { } } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-restricted-globals': ['error', 'status'] @@ -362,7 +362,7 @@ function foo({ bar }: { bar: string }) { console.log(bar); } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-dupe-args': 'error', @@ -385,7 +385,7 @@ export default class ListModalStore { orderList: IObservableArray = observable([]); } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-unused-vars': 'error' @@ -407,7 +407,7 @@ function test(file: Blob) { return slice } `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', rules: { 'no-use-before-define': 'error' @@ -426,7 +426,7 @@ window.whatevs = { } }; `; - const config = { + const config: Linter.Config = { parser: 'typescript-eslint-parser', parserOptions: { sourceType: 'module' diff --git a/yarn.lock b/yarn.lock index 6d9887af7619..f59697fedfe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -788,6 +788,24 @@ resolved "https://registry.yarnpkg.com/@types/babel-code-frame/-/babel-code-frame-6.20.1.tgz#e79a40ea81435034df7b46b5e32e8ed638aea4dd" integrity sha1-55pA6oFDUDTfe0a14y6O1jiupN0= +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + +"@types/eslint@^4.16.5": + version "4.16.5" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-4.16.5.tgz#f0b56e011a3f7d01a380a568776f93ec56d7c911" + integrity sha512-103C3Adr8UaucsjYBDdKzL9AZk6c6F2gKIlyZOxv48KtmnvNcXoDsEddF4N/DZJNoVFg6NGSbzYodvxix3Md2g== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -807,6 +825,11 @@ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.12.tgz#7e0ced251fa94c3bc2d1023d4b84b2992fa06376" integrity sha512-/kQvbVzdEpOq4tEWT79yAHSM4nH4xMlhJv2GrLVQt4Qmo8yYsPdioBM1QpN/2GX1wkfMnyXvdoftvLUr0LBj7Q== +"@types/json-schema@*": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.1.tgz#fcaa655260285b8061850789f8268c51a4ec8ee1" + integrity sha512-NVQEMviDWjuen3UW+mU1J6fZ0WhOfG1yRce/2OTcbaz+fgmTw2cahx6N2wh0Yl+a+hg2UZj/oElZmtULWyGIsA== + "@types/lodash.isplainobject@^4.0.4": version "4.0.4" resolved "https://registry.yarnpkg.com/@types/lodash.isplainobject/-/lodash.isplainobject-4.0.4.tgz#ac28008a145ea19ac9f6dc46045aa92e11a09322"