Typescript: Rename a symbol of a named export: Do not create export alias

Created on 14 Dec 2018  ·  19Comments  ·  Source: microsoft/TypeScript

  • VSCode Version: 1.30
  • OS Version: Win 10

When I rename a symbol which is a named export in a module, then there is just an alias created in the module export (VS Code 1.30). What I would expect is that the symbol is renamed in the module export AND all in all modules that are importing it (that is the bevavior of 1.29.1). Or an option by which I can specify the old behavior. This feature is soo useful to rename a bunch of modules.

Release notes of 1.30 only include some rename changes for destructuring , but I did not have any destructuring in code.

Old (1.29.1):

vscode_1 29 1

New (1.30):

vscode_1 30

Does this issue occur when all extensions are disabled?: Yes, running clean versions of 1.30, 1.29.1

PS: Typescript 3.2.2 in both tests.

// EDIT:

Actually, after all VS Code 1.29.1 did use Typescript 3.1.4 in the first test, not 3.2.2. Switching to TS 3.2.2 with the old 1.29.1 version, the same behavior (just aliasing the export instead of renaming in the whole workspace) reoccurs.
I am not sure, if there are interdependencies between VS Code and TS and therefore leave the issue open or not?

In Discussion Suggestion

Most helpful comment

I'll second this: a global option for the old behaviour feels necessary. This new alias does not work at all with the way some people work and imposing this new "feature" on people for something as common as symbol rename is not nice.

I'm sorry but for me the "improved" version is actually felt like a bug that is now preventing me from using renaming all together: I don't want my codebase to be littered with aliases.

Just let us rename stuff please. Even a rollback of the feature altogether would be better, with an option to opt-in for alias renaming when things are properly figured out.

All 19 comments

While we didn't explicitly mention exports, symbolically they behave very similarly to destructuring and I don't see why we wouldn't have made them behave the same way.

_However_, I can understand wanting a rename mode that works the old way, too - so i'll make this as a suggestion.

The new behavior would be handy occasionally, but I would prefer the old one most of the time.

Honestly, this new export alias behavior is cumbersome for refactorings. If you have something like export {Y} and you rename it to Y2, the result is

export {Y as Y2}

In order to get all symbols in the module to be also named Y2, I have to manually delete Y in the export and then fix all Y lines in the module. I also have to pay attention, that I rename the symbol Y in the export statement itself (not somewhere else in the module). Otherwise, there is just an alias created in the export and the rest of the workspace that imports Y does not get the new name.

Before, I could just grab any reference of Y symbol, press F2 and it gets renamed in all places (module+workspace).

All in all, I also would really appreciate to have the old behavior back

This also effects renaming a property (destructuring). Then after a rename I suddenly have tons of these aliased properties in my code base that I don't need. Not a good default behavior. A default behavior is always a compromise, but should be more sensible then not. And this isn't the case here.

It would be great if we can have both renaming behaviors at the same time, rather than disabling some behavior once for all.

9 times out of 10 I would prefer it to work like the old way.

For example, using destructuring (not imports):

const initialState = {
  hello: 'there'
}

export class App extends Component<Props, typeof initialState> {
  state = initialState

  async componentDidMount() {
    const { hello } = this.state;
  }
}

When I Rename Symbol on hello in the function I want it to rename hello in initialState too. And vice versa.

I usually do not get naming right the first time around. Often I'll just go w/ x to not get hung up on naming until I get something working, and maybe rename things a few times before I'm done. The old behavior of rename symbol was great for this.

I'm 😢this behavior was changed without providing an option to maintain the old behavior.

By the way: Same thing with imports - it even takes longer here.
Say during work in module a I notice, that symbol B is not a suitable name for that type.

Module a:

import {B} from "./b"   // *1

type A = {
 b: B // *2
}

Module b:

type B = {  // *3
 ...
}

export {B} // *4

If I change it in the places *1 or *2, only an import alias is created in module a. Next step: Go to module b. I cannot rename*3, otherwise same unexpected aliasing. So I have to find place *4 and apply the refactoring. After that we are still not done, as said above: All symbols in workspace are renamed, but we have to manually delete the created alias by VS Code in *4 and rename all places in the module b itself.

Before: F2. 😉

I really shy at renaming things since this change. Has this issue already somehow been discussed by VS Code team?

i would not hate new renaming as much if it was smart enough so that after renaming it wasn't like:

import { x as x } ...
const { x: x } = ....
const ... = { x: x }

but rather like

import { x } ...
const { x } = ....
const ... = { x }

I'll second this: a global option for the old behaviour feels necessary. This new alias does not work at all with the way some people work and imposing this new "feature" on people for something as common as symbol rename is not nice.

I'm sorry but for me the "improved" version is actually felt like a bug that is now preventing me from using renaming all together: I don't want my codebase to be littered with aliases.

Just let us rename stuff please. Even a rollback of the feature altogether would be better, with an option to opt-in for alias renaming when things are properly figured out.

I tried to refactor a prop from a parent React Component with a child SFC, and got the following (crazy) behaviour:

Before rename

// Parent Component
<ChildComponent
    hasError={this.state.disabled}
/>

// Child Component
interface ChildProps {
    hasError: boolean;
}
ChildComponent: React.SFC<ChildProps> =({
    hasError,
}) => (<div>{hasError}</div>);

After rename

// Parent Component
<ChildComponent
    disabled={this.state.disabled}
/>

// Child Component
interface ChildProps {
    disabled: boolean;
}
ChildComponent: React.SFC<ChildProps> =({
    hasError: disabled,
}) => (<div>{hasError}</div>);

It correctly renamed the interface, then aliased the props for actual usage in the ChildComponent(!) This cannot be the desired behaviour...

As workaround, until this issue will be fixed, I let VSCode _Rename Symbol_ the alias in the export from:

export { test11 as test1 }

to:

export { test11 as test11 }

and then delete the alias:

export { test11 }

This behaviour is terrible.

It's 2020 now, any further progress?

Isn't there a fix yet?

Isn't there a fix yet?

Apparently for someone, somewhere, this is how it is _supposed_ to work!

Isn't there a fix yet?

Apparently for someone, somewhere, this is how it is _supposed_ to work!

Crazy :)))
And considering the amount of votes, up to 17 on one of the issues...
Need to create another issue probably

Hey, i was wondering about the same thing.

I thought rename refactoring was super-cool until i realized that when you use object destructuring it uses aliases instead of renaming.

Is there any workaround or fix coming soon?

Hey, i was wondering about the same thing.

I thought rename refactoring was super-cool until i realized that when you use object destructuring it uses aliases instead of renaming.

Is there any workaround or fix coming soon?

Yeah, its completely stupid.

Does the setting typescript.preferences.useAliasesForRenames in vscode solve the problem?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antony-Jones picture Antony-Jones  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

DanielRosenwasser picture DanielRosenwasser  ·  3Comments

dlaberge picture dlaberge  ·  3Comments

weswigham picture weswigham  ·  3Comments