From 5fd2cc12d41f78a280dcbe1f639f29c89f2c78aa Mon Sep 17 00:00:00 2001 From: Rebecca Stevens Date: Sun, 1 Aug 2021 21:43:41 +1200 Subject: [PATCH] refactor: tidy up conditional imports importing --- .../src/conditional-imports/index.ts | 2 + .../src/conditional-imports/tsutils.ts | 8 +-- .../src/conditional-imports/typescript.ts | 8 +-- .../src/eslint-utils/isTypeReadonly.ts | 67 +++++++++---------- .../src/eslint-utils/propertyTypes.ts | 18 ++--- 5 files changed, 50 insertions(+), 53 deletions(-) create mode 100644 packages/experimental-utils/src/conditional-imports/index.ts diff --git a/packages/experimental-utils/src/conditional-imports/index.ts b/packages/experimental-utils/src/conditional-imports/index.ts new file mode 100644 index 000000000000..ea0246926c40 --- /dev/null +++ b/packages/experimental-utils/src/conditional-imports/index.ts @@ -0,0 +1,2 @@ +export * from './tsutils'; +export * from './typescript'; diff --git a/packages/experimental-utils/src/conditional-imports/tsutils.ts b/packages/experimental-utils/src/conditional-imports/tsutils.ts index 9cd99d19aca6..54d5cd899346 100644 --- a/packages/experimental-utils/src/conditional-imports/tsutils.ts +++ b/packages/experimental-utils/src/conditional-imports/tsutils.ts @@ -1,12 +1,12 @@ -import type * as tsutils from 'tsutils'; +import type * as tsutilsType from 'tsutils'; // Conditionally loaded tsutils but only if it is available. -const conditionalTsutils = ((): typeof tsutils | Error => { +const tsutils = ((): typeof tsutilsType | Error => { try { - return require('tsutils') as typeof tsutils; + return require('tsutils') as typeof tsutilsType; } catch { return new Error('Cannot find local tsutils peer depenancy.'); } })(); -export { conditionalTsutils }; +export { tsutils }; diff --git a/packages/experimental-utils/src/conditional-imports/typescript.ts b/packages/experimental-utils/src/conditional-imports/typescript.ts index 12f8d9d89dc3..ee20b10b1512 100644 --- a/packages/experimental-utils/src/conditional-imports/typescript.ts +++ b/packages/experimental-utils/src/conditional-imports/typescript.ts @@ -1,12 +1,12 @@ -import type * as ts from 'typescript'; +import type * as tsType from 'typescript'; // Conditionally loaded TypeScript but only if it is available. -const conditionalTypeScript = ((): typeof ts | Error => { +const ts = ((): typeof tsType | Error => { try { - return require('typescript') as typeof ts; + return require('typescript') as typeof tsType; } catch { return new Error('Cannot find local typescript peer depenancy.'); } })(); -export { conditionalTypeScript }; +export { ts }; diff --git a/packages/experimental-utils/src/eslint-utils/isTypeReadonly.ts b/packages/experimental-utils/src/eslint-utils/isTypeReadonly.ts index 99ec83d22e49..21b8fa4b1f1b 100644 --- a/packages/experimental-utils/src/eslint-utils/isTypeReadonly.ts +++ b/packages/experimental-utils/src/eslint-utils/isTypeReadonly.ts @@ -1,8 +1,7 @@ import assert from 'assert'; -import type * as ts from 'typescript'; +import type * as tsTypes from 'typescript'; -import { conditionalTypeScript } from '../conditional-imports/typescript'; -import { conditionalTsutils } from '../conditional-imports/tsutils'; +import { ts, tsutils } from '../conditional-imports'; import { getTypeOfPropertyOfType } from './propertyTypes'; import { nullThrows, NullThrowsReasons } from './nullThrows'; @@ -17,11 +16,11 @@ const enum Readonlyness { } function isTypeReadonlyArrayOrTuple( - checker: ts.TypeChecker, - type: ts.Type, - seenTypes: Set, + checker: tsTypes.TypeChecker, + type: tsTypes.Type, + seenTypes: Set, ): Readonlyness { - function checkTypeArguments(arrayType: ts.TypeReference): Readonlyness { + function checkTypeArguments(arrayType: tsTypes.TypeReference): Readonlyness { const typeArguments = // getTypeArguments was only added in TS3.7 checker.getTypeArguments @@ -73,14 +72,14 @@ function isTypeReadonlyArrayOrTuple( } function isTypeReadonlyObject( - checker: ts.TypeChecker, - type: ts.Type, - seenTypes: Set, + checker: tsTypes.TypeChecker, + type: tsTypes.Type, + seenTypes: Set, ): Readonlyness { - assert(!(conditionalTypeScript instanceof Error)); - assert(!(conditionalTsutils instanceof Error)); + assert(!(ts instanceof Error)); + assert(!(tsutils instanceof Error)); - function checkIndexSignature(kind: ts.IndexKind): Readonlyness { + function checkIndexSignature(kind: tsTypes.IndexKind): Readonlyness { const indexInfo = checker.getIndexInfoOfType(type, kind); if (indexInfo) { return indexInfo.isReadonly @@ -96,7 +95,7 @@ function isTypeReadonlyObject( // ensure the properties are marked as readonly for (const property of properties) { if ( - !conditionalTsutils.isPropertyReadonlyInType( + !tsutils.isPropertyReadonlyInType( type, property.getEscapedName(), checker, @@ -133,16 +132,12 @@ function isTypeReadonlyObject( } } - const isStringIndexSigReadonly = checkIndexSignature( - conditionalTypeScript.IndexKind.String, - ); + const isStringIndexSigReadonly = checkIndexSignature(ts.IndexKind.String); if (isStringIndexSigReadonly === Readonlyness.Mutable) { return isStringIndexSigReadonly; } - const isNumberIndexSigReadonly = checkIndexSignature( - conditionalTypeScript.IndexKind.Number, - ); + const isNumberIndexSigReadonly = checkIndexSignature(ts.IndexKind.Number); if (isNumberIndexSigReadonly === Readonlyness.Mutable) { return isNumberIndexSigReadonly; } @@ -152,18 +147,18 @@ function isTypeReadonlyObject( // a helper function to ensure the seenTypes map is always passed down, except by the external caller function isTypeReadonlyRecurser( - checker: ts.TypeChecker, - type: ts.Type, - seenTypes: Set, + checker: tsTypes.TypeChecker, + type: tsTypes.Type, + seenTypes: Set, ): Readonlyness.Readonly | Readonlyness.Mutable { - assert(!(conditionalTypeScript instanceof Error)); - assert(!(conditionalTsutils instanceof Error)); + assert(!(ts instanceof Error)); + assert(!(tsutils instanceof Error)); seenTypes.add(type); - if (conditionalTsutils.isUnionType(type)) { + if (tsutils.isUnionType(type)) { // all types in the union must be readonly - const result = conditionalTsutils + const result = tsutils .unionTypeParts(type) .every(t => isTypeReadonlyRecurser(checker, t, seenTypes)); const readonlyness = result ? Readonlyness.Readonly : Readonlyness.Mutable; @@ -172,10 +167,7 @@ function isTypeReadonlyRecurser( // all non-object, non-intersection types are readonly. // this should only be primitive types - if ( - !conditionalTsutils.isObjectType(type) && - !conditionalTsutils.isUnionOrIntersectionType(type) - ) { + if (!tsutils.isObjectType(type) && !tsutils.isUnionOrIntersectionType(type)) { return Readonlyness.Readonly; } @@ -205,12 +197,15 @@ function isTypeReadonlyRecurser( /** * Checks if the given type is readonly */ -function isTypeReadonly(checker: ts.TypeChecker, type: ts.Type): boolean { - if (conditionalTypeScript instanceof Error) { - throw conditionalTypeScript; +function isTypeReadonly( + checker: tsTypes.TypeChecker, + type: tsTypes.Type, +): boolean { + if (ts instanceof Error) { + throw ts; } - if (conditionalTsutils instanceof Error) { - throw conditionalTsutils; + if (tsutils instanceof Error) { + throw tsutils; } return ( diff --git a/packages/experimental-utils/src/eslint-utils/propertyTypes.ts b/packages/experimental-utils/src/eslint-utils/propertyTypes.ts index efeaf7beb482..83ad61d7dd7f 100644 --- a/packages/experimental-utils/src/eslint-utils/propertyTypes.ts +++ b/packages/experimental-utils/src/eslint-utils/propertyTypes.ts @@ -1,11 +1,11 @@ -import type * as ts from 'typescript'; +import type * as tsType from 'typescript'; export function getTypeOfPropertyOfName( - checker: ts.TypeChecker, - type: ts.Type, + checker: tsType.TypeChecker, + type: tsType.Type, name: string, - escapedName?: ts.__String, -): ts.Type | undefined { + escapedName?: tsType.__String, +): tsType.Type | undefined { // Most names are directly usable in the checker and aren't different from escaped names if (!escapedName || !name.startsWith('__')) { return checker.getTypeOfPropertyOfType(type, name); @@ -23,10 +23,10 @@ export function getTypeOfPropertyOfName( } export function getTypeOfPropertyOfType( - checker: ts.TypeChecker, - type: ts.Type, - property: ts.Symbol, -): ts.Type | undefined { + checker: tsType.TypeChecker, + type: tsType.Type, + property: tsType.Symbol, +): tsType.Type | undefined { return getTypeOfPropertyOfName( checker, type,