From f4b547b99f2874958b95da95b516046bde6a487e Mon Sep 17 00:00:00 2001 From: Bauke Date: Fri, 25 Feb 2022 01:34:11 +0100 Subject: [PATCH] Type features explicitly. --- source/options/features.ts | 39 ++++++++++++++++++++------------------ source/options/options.ts | 8 ++++---- source/types.d.ts | 11 +++++++++++ 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/source/options/features.ts b/source/options/features.ts index eba7d73..0bac939 100644 --- a/source/options/features.ts +++ b/source/options/features.ts @@ -1,3 +1,4 @@ +import Settings from '../settings.js'; import { AboutSetting, AnonymizeUsernamesSetting, @@ -10,66 +11,68 @@ import { UsernameColorsSetting, } from './components/exports.js'; -/** - * The array of features available in TRX. - * * The index exists to sort the sidebar listing. - * * The key should match the corresponding key from `Settings.features`. - * * The value should be the header title for display. - * * The component function should return the corresponding settings components. - */ -export const features = [ +type Feature = { + index: number; + key: keyof RemoveIndexSignature; + title: string; + component: () => any; +}; + +export const features: Feature[] = [ { index: 0, key: 'anonymizeUsernames', - value: 'Anonymize Usernames', + title: 'Anonymize Usernames', component: () => AnonymizeUsernamesSetting, }, { index: 0, key: 'autocomplete', - value: 'Autocomplete', + title: 'Autocomplete', component: () => AutocompleteSetting, }, { index: 0, key: 'backToTop', - value: 'Back To Top', + title: 'Back To Top', component: () => BackToTopSetting, }, { index: 0, key: 'hideVotes', - value: 'Hide Votes', + title: 'Hide Votes', component: () => HideVotesSetting, }, { index: 0, key: 'jumpToNewComment', - value: 'Jump To New Comment', + title: 'Jump To New Comment', component: () => JumpToNewCommentSetting, }, { index: 0, key: 'markdownToolbar', - value: 'Markdown Toolbar', + title: 'Markdown Toolbar', component: () => MarkdownToolbarSetting, }, { index: 0, key: 'userLabels', - value: 'User Labels', + title: 'User Labels', component: () => UserLabelsSetting, }, { index: 0, key: 'usernameColors', - value: 'Username Colors', + title: 'Username Colors', component: () => UsernameColorsSetting, }, { index: 1, key: 'debug', - value: 'About & Info', + title: 'About & Info', component: () => AboutSetting, }, -].sort((a, b) => a.index - b.index); +]; + +features.sort((a, b) => a.index - b.index); diff --git a/source/options/options.ts b/source/options/options.ts index 7f65ba4..bc3a9aa 100644 --- a/source/options/options.ts +++ b/source/options/options.ts @@ -97,7 +97,7 @@ class App extends Component { const tildesLink = html`<${Link} text="Tildes" url="${tildesURL}" />`; const asideElements = features.map( - ({key, value}) => + ({key, title}) => html`
  • { this.setActiveFeature(key); }}" > - ${value} + ${title}
  • `, ); const mainElements = features.map( - ({key, value, component}) => + ({key, title, component}) => html` <${component()} class="${activeFeature === key ? '' : 'trx-hidden'}" enabled="${enabledFeatures.has(key)}" feature=${key} key=${key} - title="${value}" + title="${title}" /> `, ); diff --git a/source/types.d.ts b/source/types.d.ts index a6b391f..93c2dec 100644 --- a/source/types.d.ts +++ b/source/types.d.ts @@ -33,4 +33,15 @@ declare global { id: number; username: string; }; + + // Removes an index signature from a type, useful for getting all defined keys + // from an object that also has an index signature, like Settings.features. + // https://stackoverflow.com/a/66252656 + type RemoveIndexSignature = { + [K in keyof T as string extends K + ? never + : number extends K + ? never + : K]: T[K]; + }; }