mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove duplication from exhaustiveness checks for discriminating unions
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
497ab273ae
commit
1a5073caad
@ -5,3 +5,13 @@
|
||||
|
||||
// See: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions
|
||||
export interface Discriminable<T extends string> { kind: T }
|
||||
|
||||
// Note: this will fail at transpilation time, if all kinds are not instructed in switch/case.
|
||||
// See: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
|
||||
export const checkThatAllDiscriminablesAreExhausted = <T extends never>(value: T) => {
|
||||
const _exhaustiveCheck: never = value;
|
||||
|
||||
return new Error(
|
||||
`Tried to exhaust discriminables, but no instructions were found for ${(_exhaustiveCheck as any).kind}`,
|
||||
);
|
||||
};
|
||||
|
||||
@ -10,6 +10,7 @@ import type { ApplicationMenuItemTypes } from "./menu-items/application-menu-ite
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { map, sortBy } from "lodash/fp";
|
||||
import type { MenuItemRoot } from "./application-menu-item-composite.injectable";
|
||||
import { checkThatAllDiscriminablesAreExhausted } from "../../../common/utils/composable-responsibilities/discriminable/discriminable";
|
||||
|
||||
const populateApplicationMenuInjectable = getInjectable({
|
||||
id: "populate-application-menu",
|
||||
@ -32,12 +33,12 @@ export default populateApplicationMenuInjectable;
|
||||
const toHierarchicalElectronMenuItem = (
|
||||
composite: Composite<ApplicationMenuItemTypes>,
|
||||
): MenuItemOpts => {
|
||||
switch (composite.value.kind) {
|
||||
const value = composite.value;
|
||||
|
||||
switch (value.kind) {
|
||||
case "top-level-menu": {
|
||||
const {
|
||||
id,
|
||||
value: { label, role },
|
||||
} = composite;
|
||||
const { id } = composite;
|
||||
const { label, role } = value;
|
||||
|
||||
return {
|
||||
...(id ? { id } : {}),
|
||||
@ -53,10 +54,8 @@ const toHierarchicalElectronMenuItem = (
|
||||
}
|
||||
|
||||
case "sub-menu": {
|
||||
const {
|
||||
id,
|
||||
value: { label },
|
||||
} = composite;
|
||||
const { id } = composite;
|
||||
const { label } = value;
|
||||
|
||||
return {
|
||||
...(id ? { id } : {}),
|
||||
@ -71,10 +70,8 @@ const toHierarchicalElectronMenuItem = (
|
||||
}
|
||||
|
||||
case "clickable-menu-item": {
|
||||
const {
|
||||
id,
|
||||
value: { label, onClick, keyboardShortcut },
|
||||
} = composite;
|
||||
const { id } = composite;
|
||||
const { label, onClick, keyboardShortcut } = value;
|
||||
|
||||
return {
|
||||
...(id ? { id } : {}),
|
||||
@ -85,9 +82,7 @@ const toHierarchicalElectronMenuItem = (
|
||||
}
|
||||
|
||||
case "os-action-menu-item": {
|
||||
const {
|
||||
value: { label, keyboardShortcut, actionName },
|
||||
} = composite;
|
||||
const { label, keyboardShortcut, actionName } = value;
|
||||
|
||||
return {
|
||||
...(label ? { label } : {}),
|
||||
@ -103,14 +98,7 @@ const toHierarchicalElectronMenuItem = (
|
||||
}
|
||||
|
||||
default: {
|
||||
// Note: this will fail at transpilation time, if all ApplicationMenuItemTypes
|
||||
// are not handled in switch/case.
|
||||
const _exhaustiveCheck: never = composite.value;
|
||||
|
||||
// Note: this code is unreachable, it is here to make ts not complain about
|
||||
// _exhaustiveCheck not being used.
|
||||
// See: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
|
||||
throw new Error(`Tried to create application menu, but foreign menu item was encountered: ${_exhaustiveCheck} ${composite.value}`);
|
||||
throw checkThatAllDiscriminablesAreExhausted(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -15,6 +15,7 @@ import { PreferencesNavigationTab } from "./preferences-navigation-tab";
|
||||
import { compositeHasDescendant } from "../../../../common/utils/composite/composite-has-descendant/composite-has-descendant";
|
||||
import type { PreferenceTabsRoot } from "../preference-items/preference-tab-root";
|
||||
import { Icon } from "../../../../renderer/components/icon";
|
||||
import { checkThatAllDiscriminablesAreExhausted } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable";
|
||||
|
||||
interface Dependencies {
|
||||
composite: IComputedValue<Composite<PreferenceTypes | PreferenceTabsRoot>>;
|
||||
@ -88,16 +89,7 @@ const toNavigationHierarchy = (composite: Composite<PreferenceTypes | Preference
|
||||
}
|
||||
|
||||
default: {
|
||||
// Note: this will fail at transpilation time, if all kinds
|
||||
// are not handled in switch/case.
|
||||
const _exhaustiveCheck: never = value;
|
||||
|
||||
// Note: this code is unreachable, it is here to make ts not complain about
|
||||
// _exhaustiveCheck not being used.
|
||||
// See: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
|
||||
throw new Error(
|
||||
`Tried to create preference navigation, but foreign item was encountered: ${_exhaustiveCheck} ${composite.value}`,
|
||||
);
|
||||
throw checkThatAllDiscriminablesAreExhausted(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -108,3 +100,4 @@ const hasContent = compositeHasDescendant<PreferenceTypes | PreferenceTabsRoot>(
|
||||
|
||||
const emptyRender = <></>;
|
||||
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import { Map } from "../../../renderer/components/map/map";
|
||||
import { observer } from "mobx-react";
|
||||
import { PreferencesNavigation } from "./preference-navigation/preferences-navigation";
|
||||
import Gutter from "../../../renderer/components/gutter/gutter";
|
||||
import { checkThatAllDiscriminablesAreExhausted } from "../../../common/utils/composable-responsibilities/discriminable/discriminable";
|
||||
|
||||
interface Dependencies {
|
||||
closePreferences: () => void;
|
||||
@ -94,16 +95,7 @@ const toPreferenceItemHierarchy = (composite: Composite<PreferenceTypes>) => {
|
||||
}
|
||||
|
||||
default: {
|
||||
// Note: this will fail at transpilation time, if all kinds
|
||||
// are not handled in switch/case.
|
||||
const _exhaustiveCheck: never = value;
|
||||
|
||||
// Note: this code is unreachable, it is here to make ts not complain about
|
||||
// _exhaustiveCheck not being used.
|
||||
// See: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
|
||||
throw new Error(
|
||||
`Tried to create preferences, but foreign item was encountered: ${_exhaustiveCheck} ${value}`,
|
||||
);
|
||||
throw checkThatAllDiscriminablesAreExhausted(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user