Skip to content

Rename refactoring that renames constructor parameter doesn't apply to its use in the constructor #7479

Closed
@dbaeumer

Description

@dbaeumer

From @kberg on March 11, 2016 3:2

Starting with

interface Person {
  firstname: string;
  lastname: string;
}

class Student {
  fullname: string;
  constructor(public firstname, public middleinitial, public lastname) {
    this.fullname = firstname + " " + middleinitial + " " + lastname;
  }
}


class Startup {
  public static greeter(person: Person) {
    return "Hello, " + person.firstname + " " + person.lastname;
  }

  public static main(): number {
    var user: Person = new Student("Jane", "M.", "User");
    console.log(Startup.greeter(user));
    return 0;
  }
}

Startup.main();

In this case, Student can pass for a Person. But if I rename Person.firstname to fname, there's another compiler error.

interface Person {
  fname: string;
  lastname: string;
}

class Student {
  fullname: string;
  constructor(public firstname, public middleinitial, public lastname) {
    this.fullname = firstname + " " + middleinitial + " " + lastname;
  }
}


class Startup {
  public static greeter(person: Person) {
    return "Hello, " + person.fname + " " + person.lastname;
  }

  public static main(): number {
    var user: Person = new Student("Jane", "M.", "User");
    console.log(Startup.greeter(user));
    return 0;
  }
}

Startup.main();

Because "Type 'Student' is not assignable to type 'Person'. Property 'fname' is missing in type 'Student'."

If, instead we concretely indicate that Student is a person,

class Student implements Person {
  fullname: string;
  constructor(public firstname, public middleinitial, public lastname) {
    this.fullname = firstname + " " + middleinitial + " " + lastname;
  }
}

Such a rename would propagate:

interface Person {
  fname: string;
  lastname: string;
}

class Student implements Person {
  fullname: string;
  constructor(public fname, public middleinitial, public lastname) {
    this.fullname = firstname + " " + middleinitial + " " + lastname;
  }
}


class Startup {
  public static greeter(person: Person) {
    return "Hello, " + person.fname + " " + person.lastname;
  }

  public static main(): number {
    var user: Person = new Student("Jane", "M.", "User");
    console.log(Startup.greeter(user));
    return 0;
  }
}

Startup.main();

Well, mostly. The constructor broke.

Copied from original issue: microsoft/vscode#3987

Metadata

Metadata

Assignees

No one assigned

    Labels

    By DesignDeprecated - use "Working as Intended" or "Design Limitation" instead

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions