From 5e9fbbb620c7786bfb5c96cd74866988a276fc25 Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Sat, 7 Mar 2020 20:08:46 +0530 Subject: [PATCH] typings improvements --- lib/actions/term-groups.ts | 6 +++--- lib/actions/ui.ts | 2 +- lib/command-registry.ts | 2 +- lib/constants/sessions.ts | 2 +- lib/constants/term-groups.ts | 2 +- lib/constants/ui.ts | 1 + lib/containers/hyper.tsx | 6 +++--- lib/hyper.d.ts | 16 ++++++++++------ lib/utils/object.ts | 4 ++++ lib/utils/plugins.ts | 30 +++++++++++++++++------------- 10 files changed, 42 insertions(+), 29 deletions(-) diff --git a/lib/actions/term-groups.ts b/lib/actions/term-groups.ts index 3070ca0a..f9e90c6a 100644 --- a/lib/actions/term-groups.ts +++ b/lib/actions/term-groups.ts @@ -10,10 +10,10 @@ import {SESSION_REQUEST} from '../constants/sessions'; import findBySession from '../utils/term-groups'; import {getRootGroups} from '../selectors'; import {setActiveSession, ptyExitSession, userExitSession} from './sessions'; -import {ITermState, ITermGroup, HyperState, HyperDispatch} from '../hyper'; +import {ITermState, ITermGroup, HyperState, HyperDispatch, HyperActions} from '../hyper'; import {Immutable} from 'seamless-immutable'; -function requestSplit(direction: string) { +function requestSplit(direction: 'VERTICAL' | 'HORIZONTAL') { return (activeUid: string) => (dispatch: HyperDispatch, getState: () => HyperState): void => { dispatch({ type: SESSION_REQUEST, @@ -32,7 +32,7 @@ function requestSplit(direction: string) { export const requestVerticalSplit = requestSplit(DIRECTION.VERTICAL); export const requestHorizontalSplit = requestSplit(DIRECTION.HORIZONTAL); -export function resizeTermGroup(uid: string, sizes: number[]) { +export function resizeTermGroup(uid: string, sizes: number[]): HyperActions { return { uid, type: TERM_GROUP_RESIZE, diff --git a/lib/actions/ui.ts b/lib/actions/ui.ts index 82443f24..172a36f7 100644 --- a/lib/actions/ui.ts +++ b/lib/actions/ui.ts @@ -318,7 +318,7 @@ export function openSSH(url: string) { }; } -export function execCommand(command: any, fn: any, e: any) { +export function execCommand(command: string, fn: (...args: any[]) => void, e: any) { return (dispatch: HyperDispatch) => dispatch({ type: UI_COMMAND_EXEC, diff --git a/lib/command-registry.ts b/lib/command-registry.ts index d585f1f4..86d89cc4 100644 --- a/lib/command-registry.ts +++ b/lib/command-registry.ts @@ -3,7 +3,7 @@ import {remote} from 'electron'; const {getDecoratedKeymaps} = remote.require('./plugins'); -let commands: Record = {}; +let commands: Record void> = {}; export const getRegisteredKeys = () => { const keymaps = getDecoratedKeymaps(); diff --git a/lib/constants/sessions.ts b/lib/constants/sessions.ts index a399d410..0ef2f5d9 100644 --- a/lib/constants/sessions.ts +++ b/lib/constants/sessions.ts @@ -22,7 +22,7 @@ export interface SessionAddAction { pid: number | null; cols: number | null; rows: number | null; - splitDirection?: string; + splitDirection?: 'HORIZONTAL' | 'VERTICAL'; activeUid: string | null; now: number; } diff --git a/lib/constants/term-groups.ts b/lib/constants/term-groups.ts index ca7c7f60..798b9e84 100644 --- a/lib/constants/term-groups.ts +++ b/lib/constants/term-groups.ts @@ -5,7 +5,7 @@ export const TERM_GROUP_EXIT_ACTIVE = 'TERM_GROUP_EXIT_ACTIVE'; export const DIRECTION = { HORIZONTAL: 'HORIZONTAL', VERTICAL: 'VERTICAL' -}; +} as const; export interface TermGroupRequestAction { type: typeof TERM_GROUP_REQUEST; diff --git a/lib/constants/ui.ts b/lib/constants/ui.ts index c54c722b..b2796216 100644 --- a/lib/constants/ui.ts +++ b/lib/constants/ui.ts @@ -96,6 +96,7 @@ export interface UIContextmenuOpenAction { } export interface UICommandExecAction { type: typeof UI_COMMAND_EXEC; + command: string; } export type UIActions = diff --git a/lib/containers/hyper.tsx b/lib/containers/hyper.tsx index d5aa6a31..b2e4afd0 100644 --- a/lib/containers/hyper.tsx +++ b/lib/containers/hyper.tsx @@ -16,7 +16,7 @@ const isMac = /Mac/.test(navigator.userAgent); class Hyper extends React.PureComponent { mousetrap!: MousetrapInstance; terms: any; - constructor(props: any) { + constructor(props: HyperProps) { super(props); this.state = { lastConfigUpdate: 0 @@ -61,7 +61,7 @@ class Hyper extends React.PureComponent this.mousetrap.reset(); } - const keys: Record = getRegisteredKeys(); + const keys = getRegisteredKeys(); Object.keys(keys).forEach(commandKeys => { this.mousetrap.bind( commandKeys, @@ -160,7 +160,7 @@ const mapStateToProps = (state: HyperState) => { const mapDispatchToProps = (dispatch: HyperDispatch) => { return { - execCommand: (command: any, fn: any, e: any) => { + execCommand: (command: string, fn: (...args: any[]) => void, e: any) => { dispatch(uiActions.execCommand(command, fn, e)); } }; diff --git a/lib/hyper.d.ts b/lib/hyper.d.ts index 30f0538e..ada18f85 100644 --- a/lib/hyper.d.ts +++ b/lib/hyper.d.ts @@ -12,7 +12,7 @@ export type ITermGroup = { uid: string; sessionUid: string | null; parentUid: string | null; - direction: string | null; + direction: 'HORIZONTAL' | 'VERTICAL' | null; sizes: number[] | null; children: string[]; }; @@ -25,6 +25,9 @@ export type ITermState = { activeRootGroup: string | null; }; +export type cursorShapes = 'BEAM' | 'UNDERLINE' | 'BLOCK'; +import {FontWeight} from 'xterm'; + export type uiState = { _lastUpdate: number | null; activeUid: string | null; @@ -58,15 +61,15 @@ export type uiState = { cursorAccentColor: string; cursorBlink: boolean; cursorColor: string; - cursorShape: string; + cursorShape: cursorShapes; cwd?: string; disableLigatures: boolean; fontFamily: string; fontSize: number; fontSizeOverride: null | number; fontSmoothingOverride: string; - fontWeight: string; - fontWeightBold: string; + fontWeight: FontWeight; + fontWeightBold: FontWeight; foregroundColor: string; fullScreen: boolean; letterSpacing: number; @@ -115,7 +118,7 @@ export type session = { title: string; uid: string; url: string | null; - splitDirection?: string; + splitDirection?: 'HORIZONTAL' | 'VERTICAL'; activeUid?: string; }; export type sessionState = { @@ -133,6 +136,7 @@ import {IUiReducer} from './reducers/ui'; export {ISessionReducer} from './reducers/sessions'; import {ISessionReducer} from './reducers/sessions'; +import {Middleware} from 'redux'; export type hyperPlugin = { getTabProps: any; getTabsProps: any; @@ -148,7 +152,7 @@ export type hyperPlugin = { mapHyperTermState: any; mapNotificationsState: any; mapTermsState: any; - middleware: any; + middleware: Middleware; onRendererWindow: any; reduceSessions: ISessionReducer; reduceTermGroups: ITermGroupReducer; diff --git a/lib/utils/object.ts b/lib/utils/object.ts index 08f9335f..831a451c 100644 --- a/lib/utils/object.ts +++ b/lib/utils/object.ts @@ -14,3 +14,7 @@ export function keys(imm: Record) { } return keysCache.get(imm); } + +export const ObjectTypedKeys = (obj: T) => { + return Object.keys(obj) as (keyof T)[]; +}; diff --git a/lib/utils/plugins.ts b/lib/utils/plugins.ts index 5fc3e365..16b7075b 100644 --- a/lib/utils/plugins.ts +++ b/lib/utils/plugins.ts @@ -11,8 +11,9 @@ import React, {PureComponent} from 'react'; import ReactDOM from 'react-dom'; import Notification from '../components/notification'; import notify from './notify'; -import {hyperPlugin, IUiReducer, ISessionReducer, ITermGroupReducer, HyperState} from '../hyper'; -import {Dispatch, Middleware} from 'redux'; +import {hyperPlugin, IUiReducer, ISessionReducer, ITermGroupReducer, HyperState, HyperDispatch} from '../hyper'; +import {Middleware} from 'redux'; +import {ObjectTypedKeys} from './object'; // remote interface to `../plugins` const plugins = remote.require('./plugins') as typeof import('../../app/plugins'); @@ -21,7 +22,7 @@ const plugins = remote.require('./plugins') as typeof import('../../app/plugins' let modules: any; // cache of decorated components -let decorated: Record = {}; +let decorated: Record> = {}; // various caches extracted of the plugin methods let connectors: { @@ -30,7 +31,7 @@ let connectors: { Hyper: {state: any[]; dispatch: any[]}; Notifications: {state: any[]; dispatch: any[]}; }; -let middlewares: any[]; +let middlewares: Middleware[]; let uiReducers: IUiReducer[]; let sessionsReducers: ISessionReducer[]; let termGroupsReducers: ITermGroupReducer[]; @@ -51,9 +52,9 @@ let reducersDecorators: { }; // expose decorated component instance to the higher-order components -function exposeDecorated(Component_: any) { - return class DecoratedComponent extends React.Component { - constructor(props: any, context: any) { +function exposeDecorated

(Component_: React.ComponentClass

): React.ComponentClass { + return class DecoratedComponent extends React.Component

{ + constructor(props: P, context: any) { super(props, context); } onRef = (decorated_: any) => { @@ -71,7 +72,7 @@ function exposeDecorated(Component_: any) { }; } -function getDecorated(parent: any, name: string) { +function getDecorated

(parent: React.ComponentClass

, name: string): React.ComponentClass

{ if (!decorated[name]) { let class_ = exposeDecorated(parent); (class_ as any).displayName = `_exposeDecorated(${name})`; @@ -116,9 +117,12 @@ function getDecorated(parent: any, name: string) { // for each component, we return a higher-order component // that wraps with the higher-order components // exposed by plugins -export function decorate(Component_: any, name: string) { - return class DecoratedComponent extends React.Component { - constructor(props: any) { +export function decorate

( + Component_: React.ComponentClass

, + name: string +): React.ComponentClass { + return class DecoratedComponent extends React.Component { + constructor(props: P) { super(props); this.state = {hasError: false}; } @@ -255,7 +259,7 @@ const loadModules = () => { return undefined; } - (Object.keys(mod) as (keyof typeof mod)[]).forEach(i => { + ObjectTypedKeys(mod).forEach(i => { if (Object.hasOwnProperty.call(mod, i)) { mod[i]._pluginName = pluginName; mod[i]._pluginVersion = pluginVersion; @@ -419,7 +423,7 @@ export function getTabProps(tab: any, parentProps: any, props: any) { // and the class gets decorated (proxied) export function connect( stateFn: (state: HyperState) => stateProps, - dispatchFn: (dispatch: Dispatch) => dispatchProps, + dispatchFn: (dispatch: HyperDispatch) => dispatchProps, c: any, d: Options = {} ) {