Skip to content

Latest commit

 

History

History
835 lines (546 loc) · 10.6 KB

Supported-Fixes.md

File metadata and controls

835 lines (546 loc) · 10.6 KB

Supported CodeFixes

The following 39 codefixes are supported by Rehearsal, which resolve 103 different TypeScript diagnostics errors.

Add Missing async Keyword

id: addMissingAsync

Adds the missing async keyword where a promise should be returned. Input:

interface Stuff {
  b: () => Promise<string>;
}
export function foo(): Stuff {
  return { b: () => 'hello' };
}
interface Stuff {
  b: () => Promise<string>;
}

function foo(): Stuff | Date {
  return { b: (_) => 'hello' };
}
const foo = <T>(x: T): string => {
  await new Promise((resolve) => resolve(true));
  return '';
};

Output:

interface Stuff {
  b: () => Promise<string>;
}
export function foo(): Stuff {
  return { b: async () => 'hello' };
}
interface Stuff {
  b: () => Promise<string>;
}
function foo(): Stuff | Date {
  return { b: async (_) => 'hello' };
}
const foo = async <T>(x: T): Promise<string> => {
  await new Promise((resolve) => resolve(true));
  return '';
};

Add Missing await Keyword

id: addMissingAwait

Adds the missing await keyword where a promise should be returned but not being properly handled. Input:

export async function fn(a: Promise<() => void>) {
  a();
}
async function fn(a: string, b: Promise<string>) {
  const x = b;
  fn(x, b);
  fn(b, b);
}

Output:

export async function fn(a: Promise<() => void>) {
  (await a)();
}
async function fn(a: string, b: Promise<string>) {
  const x = await b;
  fn(x, b);
  fn(await b, b);
}

Add await To Initializers

id: addMissingAwaitToInitializer

Adds missing await keyword to declarations and expressions.

Add Missing Const

id: addMissingConst

Adds const to all unresolved variables Input:

export function sound() {
  for (x of []) {
    x;
  }
}

Output:

export function sound() {
  for (const x of []) {
    x;
  }
}

Add Missing Type Constraint

id: addMissingConstraint

Adds an extends keyword to constrain a generic type parameter. Input:

export function f<T>(x: T) {
  const y: `${number}` = x;
  y;
}

Output:

export function f<T extends `${number}`>(x: T) {
  const y: `${number}` = x;
  y;
}

Add Missing Property Declaration

id: addMissingDeclareProperty

Adds a declare keyword to properties. Input:

class B {
  p = 1;
}

export class C extends B {
  p: number;
}

Output:

class B {
  p = 1;
}

export class C extends B {
  override declare p: number;
}

Add Declaration For Decorator

id: addMissingInvocationForDecorator

Turns decorators into invocations where appropriate. Input:

declare function foo(): (...args: any[]) => void;
export class C {
  @foo
  bar() {}
}

Output:

declare function foo(): (...args: any[]) => void;
export class C {
  @foo()
  bar() {}
}

Add new Operator

id: addMissingNewOperator

Adds new operator where it is needed. Input:

export class C {
  constructor(_num?: number) {}
}
export var b = C(3);

Output:

export class C {
  constructor(_num?: number) {}
}
export var b = new C(3);

Add Optional Property

id: addOptionalPropertyUndefined

Adds undefined to the type of an optional field.

Add void To Promise

id: addVoidToPromise

Adds the void as the type parameter of Promise where appropriate. Input:

export const p1 = new Promise((resolve) => resolve());

Output:

export const p1 = new Promise<void>((resolve) => resolve());

Add Super To Constructor

id: constructorForDerivedNeedSuperCall

Adds a call the super class within the constructor. Input:

class Base {}

export class C extends Base {
  constructor() {}
}

Output:

class Base {}

export class C extends Base {
  constructor() {
    super();
  }
}

Convert To Type Export

id: convertToTypeOnlyExport

Adds type to exports where the entity(s) that is exported is a type(s). Input:

export { A, B } from '../sample-1.js';

Output:

export type { A, B } from '../sample-1.js';

Convert @typedef to Type

id: convertTypedefToType

Converts JSDoc typedef to TypeScript type(s). Input:

/**
 * @typedef {(number|string|undefined)} Foo
 */
/**
 * @typedef {object} Person
 * @property {object} data
 * @property {string} data.name
 * @property {number} data.age
 * @property {object} data.contact
 * @property {string} data.contact.address
 * @property {string} [data.contact.phone]
 */
export class Example {
  /**
   * @typedef {{ count: number }} Counter
   * @returns {Counter}
   */
  something() {
    return { count: 0 };
  }

  // @typedef {{ count: number }} Counter
  somethingElse() {
    return { count: 0 };
  }

  somethingDifferent() {
    /**
     * @typedef {{ count: number }} Counter
     */
    return { count: 0 };
  }
}

Output:

  type Foo = (number | string | undefined);
  interface Person {
    data: {
      name: string;
      age: number;
      contact: {
        address: string;
        phone?: string;
      };
    };
  }
export class Example {
  /**
   * @typedef {{ count: number }} Counter
   * @returns {Counter}
   */
  something() {
    return { count: 0 };
  }

  // @typedef {{ count: number }} Counter
  somethingElse() {
    return { count: 0 };
  }

  somethingDifferent() {
    /**
     * @typedef {{ count: number }} Counter
     */
    return { count: 0 };
  }
}

Convert to Type Only Import

id: convertToTypeOnlyImport

Adds type to imports where the entity(s) being imported are type(s). Input:

import { B, C } from '../sample-1.js';

declare const b: B;
declare const c: C;
console.log(b, c);

Output:

  import type { B, C } from '../sample-1.js';

declare const b: B;
declare const c: C;
console.log(b, c);

Delete Unused Parameter

id: deleteUnmatchedParameter

Deletes parameters that are documented but not in the implementation. Input:

/**
 * @param {number} a
 * @param {string} b
 */
export function foo(a: number) {
  console.log(a);
}

Output:

  /**
   * @param {number} a
   */
export function foo(a: number) {
  console.log(a);
}

Convert extends To implements On Interfaces

id: extendsInterfaceBecomesImplements

Converts extends to implements when interfaces are extended but empty. Input:

interface I {}
export class C extends I {}

Output:

interface I {}
export class C implements I {}

Adds await To Sync Function

id: fixAwaitInSyncFunction

Add async modifier to containing function. Input:

export const f = function () {
  await Promise.resolve();
};

Output:

export const f = async function () {
  await Promise.resolve();
};

Cannot Find Module

id: fixCannotFindModule

Attempts to download type modules for modules that can not be resolved.

Enable JSX

id: fixEnableJsxFlag

When JSX is detected, enable the tsconfig configuration for JSX.

Fix Import Of Non-Exported Member

id: fixImportNonExportedMember

Modifies the file that is being imported to expose the correct members. Input:

import { T2 } from './fail-1';
const a = 1;
const b = 1;
export { a, b };

type T2 = number;
type T1 = number;
export type { T1 };

Output:

import { T2 } from './pass-1';
const a = 1;
const b = 1;
export { a, b };

type T2 = number;
type T1 = number;
export type { T1, T2 };

Add Missing Attribute

id: fixMissingAttributes

Adds an attribute to a JSX element if it missing.

Fix Missing Member

id: fixMissingMember

Ensures that there is a type or implementation associated with a member. Input:

export class C {
  method() {
    this.x = 0;
  }
}

Output:

export class C {
  [x: string]: number;
  x: number;
  method() {
    this.x = 0;
  }
}

Add Missing Property

id: fixMissingProperties

Adds properties that are missing from objects. Input:

interface I1 {
  foo: string;
}

export const a: I1 = {};

Output:

interface I1 {
  foo: string;
}

export const a: I1 = {
  foo: ""
};

Fix Override Modifier

id: fixOverrideModifier

Adds the override modifier where the subclass is overriding the method. Input:

export class B {
  foo(_v: string) {}
  fooo(_v: string) {}
}

export class D extends B {
  fooo(_v: string) {}
}

Output:

export class B {
  foo(_v: string) {}
  fooo(_v: string) {}
}

export class D extends B {
  override fooo(_v: string) {}
}

Fix Return Type Of Async Functions

id: fixReturnTypeInAsyncFunction

Adds Promise<...> to the return type. Input:

export async function fn(): null {
  return null;
}

Output:

export async function fn(): Promise<null> {
  return null;
}

Fix Imports

id: import

Fixes missing imports.

Infer From Usage

id: inferFromUsage

Infers the types based on how the value is being used. Input:

export function f(x, y) {
  x = 0 + x;
  y = '' + y;
}

Output:

export function f(x: number, y: string) {
  x = 0 + x;
  y = '' + y;
}

Invalid Import Syntax

id: invalidImportSyntax

Fixes issues related to assignability of imports.

Add Types From JSDoc

id: jdocTypes

Annotates code with the types from the declared JSDoc comments.

Remove Unnecessary Await

id: removeUnnecessaryAwait

Removes await where the function is not async. Input:

export function foo() {
  return 1;
}

await foo();

Output:

export function foo() {
  return 1;
}

  foo();

Strict Class Initialization

id: strictClassInitialization

Fixes classes so they are initialized correctly.

Use Default Import

id: useDefaultImport

Converts namespaced import default imports.

Annotate Strict Types From JSDoc

id: annotateWithStrictTypeFromJSDoc

Annotates code with the only strict types from the declared JSDoc comments. Strict replacement for annotateWithTypeFromJSDoc

Add Error Cast

id: addErrorTypeGuard

Adds a cast to Error objects in catch clauses

Add Missing Types From Inheritance Chain

id: addMissingTypesBasedOnInheritance

Adds types to sub-class by looking at the types from the heritage.

Make Member Optional

id: makeMemberOptional

Safely makes the access to properties optional.

Add Missing Export

id: addMissingExport

Exports members that are required and used by other exports.

Add Missing Return Type

id: inferReturnType

Adds the return type to methods and functions.