1
export interface ObservableCrate<T> {
  get(): T;
  set(value: T): void;
}

export type ObservableCrateBuilder<T> = {
  build(): ObservableCrate<T>;
} & (
  T extends string | number | symbol
    ? {
      withHandlers(transitionHandlers: ObservableCrateTransitionHandlers<T>): ObservableCrate<T>;
    }
    : {}
);

export interface ObservableCrateFactory {
  <T>(initialValue: T): ObservableCrateBuilder<T>;
}

export type ObservableCrateTransitionHandlers<T extends string | number | symbol> = Partial<Record<T, Partial<Record<T, () => void>>>>;


declare const observableCrate: ObservableCrateFactory;

export enum State {
  Open = "open",
  Close = "close",
}

const crate = observableCrate(State.Close).withHandlers({});

Intelisense splits out the enum variants which breaks the typing

However, if I were to declare a variable with paramater directly it is valid and doesn't get split up:

const handlers: ObservableCrateTransitionHandlers<State> = {};

Here is a ts playground

From what I can tell it has something to do with the T extends string | number | symbol that is required for using in Record

  • [Please replace/supplement images of code/errors with plaintext versions.](https://meta.stackoverflow.com/a/285557/2887218) – jcalz Jun 23 '22 at 17:37
  • It's not clear to me what you're asking here. Can you please either add comments to the code that show the difference between what you expect and what is happening, or even better, code that produces an error where one is not expected (or vice versa)? For example, what type do you expect `crate` to be? What type do you expect `ObservableCrateBuilder` to be? – jcalz Jun 23 '22 at 17:44
  • Does [this approach](https://tsplay.dev/NV4RMW) meet your needs? If so I can write up an answer (or possibly close as duplicate of a question about distributive conditional types). If not, what am I missing? – jcalz Jun 23 '22 at 17:44
  • @jcalz Yes that approach does work indeed I just don't understand why the `[]` is needed or is correct. – Sebastian Malton Jun 23 '22 at 18:44
  • Your original type is a [distributive conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types) and I changed it into a non-distributive one by wrapping the check in `[]`, to "clothe" the bare type parameter. See the answers to the linked questions for more information. – jcalz Jun 23 '22 at 18:48

0 Answers0