unsplash/sum-types

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

Opened this issue · 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?

Screen.Recording.2021-09-13.at.17.55.23.mov

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'].

Potentially related TS issues:

🤞 Hopefully it will be fixed in TS soon.

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