Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bump TypeScript and typescript-eslint to latest, including ts-api-utils #1123

Merged
merged 9 commits into from
Sep 7, 2023
Merged
6 changes: 1 addition & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
extends: ["plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking", "prettier"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/strict-type-checked", "plugin:@typescript-eslint/stylistic-type-checked"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.eslint.json",
Expand All @@ -9,9 +9,5 @@ module.exports = {
rules: {
"deprecation/deprecation": "error",
"no-only-tests/no-only-tests": "error",

// These rules are off because we don't want them
// "@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
},
};
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"minimatch": "^8.0.0",
"mz": "^2.7.0",
"strip-ansi": "^6.0.0",
"tsutils": "^3.21.0",
"typescript": "^4.2.4"
"ts-api-utils": "^1.0.3",
"typescript": "^5.1.6"
},
"description": "Converts JavaScript to TypeScript and TypeScript to better TypeScript.",
"devDependencies": {
Expand All @@ -31,8 +31,8 @@
"@types/node": "18.17.14",
"@types/prop-types": "15.7.5",
"@types/react": "18.2.21",
"@typescript-eslint/eslint-plugin": "4.33.0",
"@typescript-eslint/parser": "4.33.0",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.4.0",
"automutate-tests": "0.5.0",
"babel-jest": "29.6.4",
"chai": "4.3.8",
Expand All @@ -52,9 +52,7 @@
},
"license": "MIT",
"lint-staged": {
"**/*.{js,json,md,ts,xml,yaml}": [
"prettier --write"
]
"**/*.{js,json,md,ts,xml,yaml}": ["prettier --write"]
},
"main": "src/index.js",
"name": "typestat",
Expand Down
2 changes: 1 addition & 1 deletion src/cli/runCli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface CliRuntime {
* @param mainRunner Method to run with parsed arguments: generally `typeStat`.
* @returns Promise for the result of running TypeStat.
*/
export const runCli = async (rawArgv: ReadonlyArray<string>, runtime?: CliRuntime): Promise<ResultStatus> => {
export const runCli = async (rawArgv: readonly string[], runtime?: CliRuntime): Promise<ResultStatus> => {
const command = new Command()
.storeOptionsAsProperties(true)
.option("-c --config [config]", "path to a TypeStat config file")
Expand Down
2 changes: 1 addition & 1 deletion src/mutations/assignments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type AssignedTypesByName = Map<string, ts.Type | string>;
/**
* Joins a set of assigned type values into a single mapping by name.
*/
export const joinAssignedTypesByName = (request: FileMutationsRequest, assignedTypeValues: ReadonlyArray<AssignedTypeValue>) => {
export const joinAssignedTypesByName = (request: FileMutationsRequest, assignedTypeValues: readonly AssignedTypeValue[]) => {
const assignedTypesByName = new Map<string, ts.Type | string>();

for (const { name, type } of assignedTypeValues) {
Expand Down
2 changes: 1 addition & 1 deletion src/mutations/codeFixes/noImplicitAny.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { FileMutationsRequest } from "../../shared/fileMutator";
Expand Down
6 changes: 3 additions & 3 deletions src/mutations/collecting.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { FileMutationsRequest } from "../shared/fileMutator";
Expand All @@ -18,7 +18,7 @@ import { findMissingFlags, isTypeFlagSetRecursively } from "./collecting/flags";
export const collectUsageFlagsAndSymbols = (
request: FileMutationsRequest,
declaredType: ts.Type,
allAssignedTypes: ReadonlyArray<ts.Type>,
allAssignedTypes: readonly ts.Type[],
) => {
// Collect which flags are later assigned to the type
const [assignedFlags, assignedTypes] = collectFlagsAndTypesFromTypes(request, allAssignedTypes);
Expand Down Expand Up @@ -56,7 +56,7 @@ export const collectUsageFlagsAndSymbols = (
*/
export const collectFlagsAndTypesFromTypes = (
request: FileMutationsRequest,
allTypes: ReadonlyArray<ts.Type>,
allTypes: readonly ts.Type[],
allowStrictNullCheckAliases?: boolean,
): [Set<ts.TypeFlags>, Set<ts.Type>] => {
const foundFlags = new Set<ts.TypeFlags>();
Expand Down
2 changes: 1 addition & 1 deletion src/mutations/collecting/flags.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { setSubtract } from "../../shared/sets";
Expand Down
6 changes: 3 additions & 3 deletions src/mutations/createExposedTypeScript.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-var-requires */
/* eslint-disable @typescript-eslint/no-dynamic-delete , @typescript-eslint/no-explicit-any, @typescript-eslint/no-var-requires */
/*
This file is a ridiculous, disgusting hack and should not be considered acceptable code to write.
Shame on you for even reading this header, let alone continuing down.
Expand Down Expand Up @@ -29,14 +29,14 @@ type ArgumentTypes<TFunction> = TFunction extends (...args: infer TArgs) => any

type ReplaceReturnType<TOriginalType, TReturnType> = (...args: ArgumentTypes<TOriginalType>) => TReturnType;

type Replace<TOriginalType, TReplacements extends any> = {
type Replace<TOriginalType, TReplacements> = {
[Property in keyof TOriginalType]: Property extends keyof TReplacements ? TReplacements[Property] : TOriginalType[Property];
};

export type ExposedTypeScript = Replace<
typeof import("typescript"),
{
createProgram: ReplaceReturnType<typeof import("typescript")["createProgram"], ExposedProgram>;
createProgram: ReplaceReturnType<(typeof import("typescript"))["createProgram"], ExposedProgram>;
}
>;

Expand Down
12 changes: 3 additions & 9 deletions src/mutations/creators.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TextInsertMutation, TextSwapMutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { FileMutationsRequest } from "../shared/fileMutator";
Expand All @@ -21,7 +21,7 @@ export const createTypeAdditionMutation = (
request: FileMutationsRequest,
node: NodeWithAddableType,
declaredType: ts.Type,
allAssignedTypes: ReadonlyArray<ts.Type>,
allAssignedTypes: readonly ts.Type[],
): TextInsertMutation | TextSwapMutation | undefined => {
// Declared 'any' types inherently can't be incomplete
if (tsutils.isTypeFlagSet(declaredType, ts.TypeFlags.Any)) {
Expand All @@ -38,9 +38,6 @@ export const createTypeAdditionMutation = (

// Join the missing types into a type string to declare
const newTypeAlias = joinIntoType(missingFlags, missingTypes, request);
if (newTypeAlias === undefined) {
return undefined;
}

// If the original type was a bottom type or just something like Function or Object, replace it entirely
if (tsutils.isTypeFlagSet(declaredType, ts.TypeFlags.Never | ts.TypeFlags.Unknown) || isKnownGlobalBaseType(declaredType)) {
Expand Down Expand Up @@ -77,7 +74,7 @@ export const createTypeCreationMutation = (
request: FileMutationsRequest,
node: NodeWithCreatableType,
declaredType: ts.Type,
allAssignedTypes: ReadonlyArray<ts.Type>,
allAssignedTypes: readonly ts.Type[],
): TextInsertMutation | undefined => {
// Find the already assigned flags and symbols, as well as any missing ones
const { assignedFlags, assignedTypes, missingFlags, missingTypes } = collectUsageFlagsAndSymbols(
Expand All @@ -93,9 +90,6 @@ export const createTypeCreationMutation = (

// Join the missing types into a type string to declare
const newTypeAlias = joinIntoType(assignedFlags, assignedTypes, request);
if (newTypeAlias === undefined) {
return undefined;
}

// Create a mutation insertion that adds the assigned types in
return {
Expand Down
2 changes: 1 addition & 1 deletion src/mutations/expansions/eliminations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { FileMutationsRequest } from "../../shared/fileMutator";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { joinIntoGenericType } from "../../../../../mutations/generics";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { createTypeAdditionMutation, createTypeCreationMutation } from "../../../../mutations/creators";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as tsutils from "tsutils";
import * as ts from "typescript";
import { getDeclaredTypesOfArgument } from "../../../../../shared/calls";
import { isPropertySignatureWithStaticName, PropertySignatureWithStaticName } from "../../../../../shared/nodeTypes";
Expand All @@ -8,10 +7,10 @@ import { FileMutationsRequest } from "../../../../../shared/fileMutator";
import { ReactComponentPropsNode } from "../getComponentPropsNode";
import { getPropNodeFromReference } from "../getPropNodeFromReference";

export type FunctionCallType = {
export interface FunctionCallType {
parameters?: (ts.Type | undefined)[];
returnValue?: ts.Type;
};
}

export const collectAllFunctionCallTypes = (request: FileMutationsRequest, propsNode: ReactComponentPropsNode) => {
const allFunctionCallTypes = new Map<PropertySignatureWithStaticName, FunctionCallType[]>();
Expand Down Expand Up @@ -50,7 +49,7 @@ const collectFunctionCallsTypes = (
// For each reference, try to infer the type from its usage...
for (const reference of references) {
// (except for the original member we're looking around)
if (reference === member || !tsutils.isExpression(reference)) {
if (reference === member || !ts.isExpression(reference)) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export const createInterfaceFromPropTypes = (
const interfaceName = `${getApparentNameOfComponent(request, node)}Props`;

const interfaceNode = ts.factory.createInterfaceDeclaration(
undefined /* decorators */,
undefined /* modifiers */,
interfaceName,
undefined /* typeParameters */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { ReactComponentNode } from "../../reactFiltering/isReactComponentNode";
Expand All @@ -16,7 +16,7 @@ type PropTypesMember = ts.PropertyDeclaration & {
*/
const getStaticPropTypes = (node: ts.ClassElement): node is PropTypesMember =>
ts.isPropertyDeclaration(node) &&
tsutils.hasModifier(node.modifiers, ts.SyntaxKind.StaticKeyword) &&
tsutils.includesModifier(node.modifiers as ts.NodeArray<ts.Modifier>, ts.SyntaxKind.StaticKeyword) &&
ts.isIdentifier(node.name) &&
node.name.text === "propTypes" &&
node.initializer !== undefined &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as tsutils from "tsutils";
import * as ts from "typescript";

import { AssignedTypesByName } from "../../../../../mutations/assignments";
Expand Down Expand Up @@ -62,7 +61,7 @@ const updateAssignedTypesForReferences = (
}

// If the reference is an indirect storage, such as a variable, recurse on *its* references
if (!tsutils.isExpression(reference)) {
if (!ts.isExpression(reference)) {
updateAssignedTypesForReferences(request, member, componentNode, reference, seenNodes, allAssignedTypes);
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const collectComponentAttributeTypes = (request: FileMutationsRequest, node: Rea
const type = typeChecker.getBaseTypeOfLiteralType(valueType);

// Add the type underneath the attribute name
const name = attribute.name.text;
const name = ts.isJsxNamespacedName(attribute.name) ? attribute.name.getText(request.sourceFile) : attribute.name.text;
const types = attributeTypes.get(name);
if (types === undefined) {
attributeTypes.set(name, [type]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { getFriendlyFileName } from "../../../../shared/fileNames";
Expand All @@ -20,7 +20,7 @@ export const getApparentNameOfComponent = (request: FileMutationsRequest, node:
}

// If the node is the default export of its file, use the file's name
if (tsutils.hasModifier(node.modifiers, ts.SyntaxKind.DefaultKeyword)) {
if (tsutils.includesModifier(node.modifiers as ts.NodeArray<ts.Modifier>, ts.SyntaxKind.DefaultKeyword)) {
return getFriendlyFileName(request.sourceFile.fileName);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { createTypeAdditionMutation } from "../../../../mutations/creators";
Expand All @@ -14,7 +14,7 @@ export const fixIncompleteReturnTypes: FileMutator = (request: FileMutationsRequ
collectMutationsFromNodes(request, isNodeVisitableFunctionLikeDeclaration, visitFunctionWithBody);

const isNodeVisitableFunctionLikeDeclaration = (node: ts.Node): node is FunctionLikeDeclarationWithType =>
tsutils.isFunctionWithBody(node) &&
ts.isFunctionLike(node) &&
// If the node has an implicit return type, we don't need to change anything
isNodeWithType(node);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { createTypeAdditionMutation, createTypeCreationMutation } from "../../../../mutations/creators";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { createTypeRemovalMutation } from "../../../../mutations/removals";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Mutation } from "automutate";
import { isTypeFlagSet } from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { isTypeFlagSetRecursively } from "../../../../mutations/collecting/flags";
Expand All @@ -21,7 +21,7 @@ const visitBinaryExpression = (node: ts.BinaryExpression, request: FileMutations
}

const declaredType = getTypeAtLocationIfNotError(request, node.left);
if (declaredType === undefined || isTypeFlagSet(declaredType, ts.TypeFlags.Any)) {
if (declaredType === undefined || tsutils.isTypeFlagSet(declaredType, ts.TypeFlags.Any)) {
return undefined;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { combineMutations, MultipleMutations, Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as ts from "typescript";
import { isTypeFlagSetRecursively } from "../../../../mutations/collecting/flags";

Expand Down Expand Up @@ -38,7 +37,7 @@ const visitCallExpression = (node: ts.CallExpression, request: FileMutationsRequ
const collectArgumentMutations = (
request: FileMutationsRequest,
callingNode: ts.CallExpression,
functionLikeValueDeclaration: ts.FunctionLikeDeclaration,
functionLikeValueDeclaration: ts.SignatureDeclaration,
): ReadonlyArray<Mutation> => {
const mutations: Mutation[] = [];
const visitableArguments = Math.min(callingNode.arguments.length, functionLikeValueDeclaration.parameters.length);
Expand Down Expand Up @@ -86,4 +85,4 @@ const collectArgumentMutation = (request: FileMutationsRequest, callingArgument:
};

const isFunctionBodyOrBlock = (node: ts.Node): node is ts.Block | ts.FunctionLikeDeclaration | ts.SourceFile =>
tsutils.isFunctionWithBody(node) || ts.isBlock(node) || ts.isSourceFile(node);
ts.isFunctionLike(node) || ts.isBlock(node) || ts.isSourceFile(node);
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as tsutils from "tsutils";
import * as ts from "typescript";

/**
Expand All @@ -13,12 +12,12 @@ export const collectReturningNodeExpressions = (functionLikeDeclaration: ts.Func
// Search through nodes within the function-like to find all its return statements
const visitNode = (node: ts.Node): void => {
// Don't look at returns within a nested function-like signature: they return for that function
if (tsutils.isFunctionWithBody(node)) {
if (ts.isFunctionLike(node)) {
return;
}

// Add new returning nodes as needed when we find any 'return' statement with a value (expression) returned
if (tsutils.isReturnStatement(node) && node.expression !== undefined) {
if (ts.isReturnStatement(node) && node.expression !== undefined) {
returnedTypes.push(node.expression);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { combineMutations, Mutation } from "automutate";
import * as tsutils from "tsutils";
import * as tsutils from "ts-api-utils";
import * as ts from "typescript";

import { isTypeFlagSetRecursively } from "../../../../mutations/collecting/flags";
Expand All @@ -16,7 +16,7 @@ export const fixStrictNonNullAssertionReturnTypes: FileMutator = (request: FileM
collectMutationsFromNodes(request, isNodeVisitableFunctionLikeDeclaration, visitFunctionWithBody);

const isNodeVisitableFunctionLikeDeclaration = (node: ts.Node): node is FunctionLikeDeclarationWithType =>
tsutils.isFunctionWithBody(node) &&
ts.isFunctionLike(node) &&
// If the node has an implicit return type, we don't need to change anything
isNodeWithType(node);

Expand Down
2 changes: 1 addition & 1 deletion src/mutators/complaint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Error and nested mutation path from a runtime failure.
*/
export class MutationsComplaint {
public constructor(public readonly error: Error, public readonly mutatorPath: ReadonlyArray<string>) {}
public constructor(public readonly error: Error, public readonly mutatorPath: readonly string[]) {}

public static wrapping(mutatorName: string, subComplaint: MutationsComplaint) {
return new MutationsComplaint(subComplaint.error, [mutatorName, ...subComplaint.mutatorPath]);
Expand Down
Loading