From cab72e1be627fb7cb06725d0a3e262e214de170f Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 4 Mar 2023 18:40:37 +0100 Subject: [PATCH] Strongly type useSettings (supersedes #559) --- src/api/settings.ts | 18 +++++++++++++++--- src/components/PluginSettings/index.tsx | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/api/settings.ts b/src/api/settings.ts index c551df03..1ca26116 100644 --- a/src/api/settings.ts +++ b/src/api/settings.ts @@ -167,11 +167,11 @@ export const Settings = makeProxy(settings); * @returns Settings */ // TODO: Representing paths as essentially "string[].join('.')" wont allow dots in paths, change to "paths?: string[][]" later -export function useSettings(paths?: string[]) { +export function useSettings(paths?: UseSettings[]) { const [, forceUpdate] = React.useReducer(() => ({}), {}); const onUpdate: SubscriptionCallback = paths - ? (value, path) => paths.includes(path) && forceUpdate() + ? (value, path) => paths.includes(path as UseSettings) && forceUpdate() : forceUpdate; React.useEffect(() => { @@ -229,7 +229,7 @@ export function definePluginSettings useSettings( - settings?.map(name => `plugins.${definedSettings.pluginName}.${name}`) + settings?.map(name => `plugins.${definedSettings.pluginName}.${name}`) as UseSettings[] ).plugins[definedSettings.pluginName] as any, def, checks: checks ?? {}, @@ -237,3 +237,15 @@ export function definePluginSettings = ResolveUseSettings[keyof T]; + +type ResolveUseSettings = { + [Key in keyof T]: + Key extends string + ? T[Key] extends Record + // @ts-ignore "Type instantiation is excessively deep and possibly infinite" + ? UseSettings extends string ? `${Key}.${UseSettings}` : never + : Key + : never; +}; diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index 3d69a607..02d89f81 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -93,7 +93,7 @@ interface PluginCardProps extends React.HTMLProps { } function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) { - const settings = useSettings([`plugins.${plugin.name}`]).plugins[plugin.name]; + const settings = useSettings([`plugins.${plugin.name}.enabled`]).plugins[plugin.name]; const isEnabled = () => settings.enabled ?? false;