sum-types icon indicating copy to clipboard operation
sum-types copied to clipboard

TS language server features for sum type members (e.g. rename)

Open OliverJAsh opened this issue 3 years ago • 3 comments

Slack discussion for reference: https://crewlabs.slack.com/archives/CFZE45NTW/p1631709631008600

With Unionize it was very easy to rename a tag in the union—TS would propagate the change to all constructors, match functions and type definitions. Can we achieve something close to this?

https://user-images.githubusercontent.com/921609/133125412-0fbee27b-c4e2-445f-80ed-f499ceb60771.mov

OliverJAsh avatar Sep 13 '21 16:09 OliverJAsh

Unfortunately I doubt this will be possible.

Renaming works if we define the union first as a record and pass that record around (i.e. the way Unionize works):

type MyRecord = { A: string; B: string };
type Constructors<T> = { [K in keyof T]: () => void };
declare const constructors: Constructors<MyRecord>;
constructors.A();

However it doesn't work if we define a union manually:

type MyUnion = { tag: 'A'; value: string } | { tag: 'B'; value: number };
type Constructors<T extends { tag: string; value: unknown }> = {
    [K in T as K['tag']]: () => void;
};
declare const constructors: Constructors<MyUnion>;
constructors.A();

It seems that renaming only works when you use K in keyof T in a mapped type, not when you do K in T as K['tag'] or K in T['tag'].

OliverJAsh avatar Sep 13 '21 17:09 OliverJAsh

Potentially related TS issues:

  • https://github.com/microsoft/TypeScript/issues/41489
  • https://github.com/microsoft/TypeScript/issues/41923
  • https://github.com/microsoft/TypeScript/issues/45549

🤞 Hopefully it will be fixed in TS soon.

OliverJAsh avatar Sep 15 '21 12:09 OliverJAsh

This is a wider issue than just renaming. It also affects other language server features such as "go to definition" and "find references". Example of go to definition from my reduced test case above:

image

OliverJAsh avatar Jun 07 '23 09:06 OliverJAsh