typing improvements

This commit is contained in:
Labhansh Agrawal 2020-06-19 18:21:34 +05:30 committed by Benjamin Staneck
parent c17c4cd7bf
commit d0e954def5
18 changed files with 56 additions and 50 deletions

View file

@ -21,9 +21,10 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
this.emit('checking-for-update');
fetch(this.updateURL)
.then((res): any => {
.then((res) => {
if (res.status === 204) {
return this.emit('update-not-available');
this.emit('update-not-available');
return;
}
// eslint-disable-next-line @typescript-eslint/camelcase
return res.json().then(({name, notes, pub_date}) => {
@ -40,7 +41,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
.catch(this.emitError.bind(this));
}
emitError(error: any) {
emitError(error: string | Error) {
if (typeof error === 'string') {
error = new Error(error);
}

View file

@ -7,7 +7,7 @@ import {cfgPath, cfgDir} from './config/paths';
import {getColorMap} from './utils/colors';
import {parsedConfig, configOptions} from '../lib/config';
const watchers: any[] = [];
const watchers: Function[] = [];
let cfg: parsedConfig = {} as any;
let _watcher: fs.FSWatcher;

View file

@ -7,7 +7,7 @@ const NEWS_URL = 'https://hyper-news.now.sh';
export default function fetchNotifications(win: BrowserWindow) {
const {rpc} = win;
const retry = (err?: any) => {
const retry = (err?: Error) => {
setTimeout(() => fetchNotifications(win), ms('30m'));
if (err) {
console.error('Notification messages fetch error', err.stack);

View file

@ -1,7 +1,7 @@
import {Notification} from 'electron';
import {icon} from './config/paths';
export default function notify(title: string, body = '', details: any = {}) {
export default function notify(title: string, body = '', details: {error?: any} = {}) {
console.log(`[Notification] ${title}: ${body}`);
if (details.error) {
console.error(details.error);

View file

@ -153,7 +153,7 @@ export default class Session extends EventEmitter {
this.batcher?.write(chunk as any);
});
this.batcher.on('flush', (data) => {
this.batcher.on('flush', (data: string) => {
this.emit('data', data);
});

View file

@ -149,7 +149,7 @@ export function newWindow(
activeUid: options.activeUid
});
session.on('data', (data: any) => {
session.on('data', (data: string) => {
rpc.emit('session data', data);
});

View file

@ -86,7 +86,7 @@ const addBinToUserPath = () => {
});
};
const logNotify = (withNotification: boolean, title: string, body: string, details?: any) => {
const logNotify = (withNotification: boolean, title: string, body: string, details?: {error?: any}) => {
console.log(title, body, details);
withNotification && notify(title, body, details);
};

View file

@ -1,6 +1,6 @@
// This is a CLI tool, using console is OK
/* eslint no-console: 0 */
import {spawn, exec} from 'child_process';
import {spawn, exec, SpawnOptions} from 'child_process';
import {isAbsolute, resolve} from 'path';
import {existsSync} from 'fs';
import {version} from '../app/package.json';
@ -42,7 +42,7 @@ args.command(
commandPromise = api
.install(pluginName)
.then(() => console.log(chalk.green(`${pluginName} installed successfully!`)))
.catch((err: any) => console.error(chalk.red(err)));
.catch((err) => console.error(chalk.red(err)));
},
['i']
);
@ -202,7 +202,7 @@ const main = (argv: string[]) => {
env['ELECTRON_ENABLE_LOGGING'] = '1';
}
const options: any = {
const options: SpawnOptions = {
detached: true,
env
};
@ -231,8 +231,8 @@ const main = (argv: string[]) => {
const child = spawn(process.execPath, args_, options);
if (flags.verbose) {
child.stdout.on('data', (data) => console.log(data.toString('utf8')));
child.stderr.on('data', (data) => console.error(data.toString('utf8')));
child.stdout?.on('data', (data) => console.log(data.toString('utf8')));
child.stderr?.on('data', (data) => console.error(data.toString('utf8')));
}
if (flags.verbose) {
return new Promise((c) => child.once('exit', () => c(null)));
@ -247,7 +247,7 @@ function eventuallyExit(code: number) {
main(process.argv)
.then(() => eventuallyExit(0))
.catch((err: any) => {
.catch((err) => {
console.error(err.stack ? err.stack : err);
eventuallyExit(1);
});

View file

@ -50,7 +50,7 @@ export function requestSession() {
};
}
export function addSessionData(uid: string, data: any) {
export function addSessionData(uid: string, data: string) {
return (dispatch: HyperDispatch) => {
dispatch({
type: SESSION_ADD_DATA,
@ -161,7 +161,7 @@ export function closeSearch(uid?: string, keyEvent?: any) {
};
}
export function sendSessionData(uid: string | null, data: any, escaped?: any) {
export function sendSessionData(uid: string | null, data: any, escaped?: boolean | null) {
return (dispatch: HyperDispatch, getState: () => HyperState) => {
dispatch({
type: SESSION_USER_DATA,

View file

@ -112,16 +112,15 @@ export function windowGeometryUpdated(): HyperActions {
// Find all sessions that are below the given
// termGroup uid in the hierarchy:
const findChildSessions = (termGroups: any, uid: string): string[] => {
const findChildSessions = (termGroups: HyperState['termGroups']['termGroups'], uid: string): string[] => {
const group = termGroups[uid];
if (group.sessionUid) {
return [uid];
}
return group.children.reduce(
(total: string[], childUid: string) => total.concat(findChildSessions(termGroups, childUid)),
[]
);
return group.children
.asMutable()
.reduce((total: string[], childUid: string) => total.concat(findChildSessions(termGroups, childUid)), []);
};
// Get the index of the next or previous group,
@ -318,7 +317,7 @@ export function openSSH(url: string) {
};
}
export function execCommand(command: string, fn: (...args: any[]) => void, e: any) {
export function execCommand(command: string, fn: (e: any, dispatch: HyperDispatch) => void, e: any) {
return (dispatch: HyperDispatch) =>
dispatch({
type: UI_COMMAND_EXEC,

View file

@ -3,7 +3,7 @@ import {HyperDispatch} from './hyper';
import {closeSearch} from './actions/sessions';
// TODO: Should be updates to new async API https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31
const {getDecoratedKeymaps} = remote.require('./plugins');
const {getDecoratedKeymaps} = remote.require('./plugins') as typeof import('../app/plugins');
let commands: Record<string, (event: any, dispatch: HyperDispatch) => void> = {
'editor:search-close': (e, dispatch) => {
@ -16,7 +16,7 @@ export const getRegisteredKeys = () => {
return Object.keys(keymaps).reduce((result: Record<string, string>, actionName) => {
const commandKeys = keymaps[actionName];
commandKeys.forEach((shortcut: string) => {
commandKeys.forEach((shortcut) => {
result[shortcut] = actionName;
});
return result;

View file

@ -12,13 +12,13 @@ const SplitPane = decorate(SplitPane_, 'SplitPane');
// eslint-disable-next-line @typescript-eslint/class-name-casing
class TermGroup_ extends React.PureComponent<TermGroupProps> {
bound: WeakMap<(uid: string, ...args: any[]) => any, Record<string, (...args: any[]) => any>>;
term?: Term_;
term?: Term_ | null;
constructor(props: TermGroupProps, context: any) {
super(props, context);
this.bound = new WeakMap();
}
bind<T extends (uid: string, ...args: any) => any>(
bind<T extends (uid: string, ...args: any[]) => any>(
fn: T,
thisObj: any,
uid: string
@ -52,7 +52,7 @@ class TermGroup_ extends React.PureComponent<TermGroupProps> {
);
}
onTermRef = (uid: string, term: Term_) => {
onTermRef = (uid: string, term: Term_ | null) => {
this.term = term;
this.props.ref_(uid, term);
};

View file

@ -3,7 +3,7 @@ import {decorate, getTermGroupProps} from '../utils/plugins';
import {registerCommandHandlers} from '../command-registry';
import TermGroup_ from './term-group';
import StyleSheet_ from './style-sheet';
import {TermsProps} from '../hyper';
import {TermsProps, HyperDispatch} from '../hyper';
import Term from './term';
import {ObjectTypedKeys} from '../utils/object';
@ -14,7 +14,7 @@ const isMac = /Mac/.test(navigator.userAgent);
export default class Terms extends React.Component<TermsProps> {
terms: Record<string, Term>;
registerCommands: (cmds: Record<string, (...args: any[]) => void>) => void;
registerCommands: (cmds: Record<string, (e: any, dispatch: HyperDispatch) => void>) => void;
constructor(props: TermsProps, context: any) {
super(props, context);
this.terms = {};
@ -29,7 +29,7 @@ export default class Terms extends React.Component<TermsProps> {
);
}
onRef = (uid: string, term: Term) => {
onRef = (uid: string, term: Term | null) => {
if (term) {
this.terms[uid] = term;
}

View file

@ -10,12 +10,13 @@ import {HeaderContainer} from './header';
import TermsContainer from './terms';
import NotificationsContainer from './notifications';
import {HyperState, HyperProps, HyperDispatch} from '../hyper';
import Terms from '../components/terms';
const isMac = /Mac/.test(navigator.userAgent);
class Hyper extends React.PureComponent<HyperProps> {
mousetrap!: MousetrapInstance;
terms: any;
terms!: Terms;
constructor(props: HyperProps) {
super(props);
}
@ -35,8 +36,8 @@ class Hyper extends React.PureComponent<HyperProps> {
}
}
handleFocusActive = (uid: string) => {
const term = this.terms.getTermByUid(uid);
handleFocusActive = (uid?: string) => {
const term = uid && this.terms.getTermByUid(uid);
if (term) {
term.focus();
}
@ -81,7 +82,7 @@ class Hyper extends React.PureComponent<HyperProps> {
window.rpc.on('term selectAll', this.handleSelectAll);
}
onTermsRef = (terms: any) => {
onTermsRef = (terms: Terms) => {
this.terms = terms;
window.focusActiveTerm = this.handleFocusActive;
};
@ -153,7 +154,7 @@ const mapStateToProps = (state: HyperState) => {
const mapDispatchToProps = (dispatch: HyperDispatch) => {
return {
execCommand: (command: string, fn: (...args: any[]) => void, e: any) => {
execCommand: (command: string, fn: (e: any, dispatch: HyperDispatch) => void, e: any) => {
dispatch(uiActions.execCommand(command, fn, e));
}
};

23
lib/hyper.d.ts vendored
View file

@ -1,10 +1,11 @@
import {Immutable} from 'seamless-immutable';
import Client from './utils/rpc';
declare global {
interface Window {
__rpcId: string;
rpc: any;
focusActiveTerm: any;
rpc: Client;
focusActiveTerm: (uid?: string) => void;
}
}
@ -154,6 +155,7 @@ export type hyperPlugin = {
mapNotificationsState: any;
mapTermsState: any;
middleware: Middleware;
onRendererUnload: any;
onRendererWindow: any;
reduceSessions: ISessionReducer;
reduceTermGroups: ITermGroupReducer;
@ -190,11 +192,12 @@ import configureStore from './store/configure-store';
export type HyperThunkDispatch = ThunkDispatch<HyperState, undefined, HyperActions>;
export type HyperDispatch = ReturnType<typeof configureStore>['dispatch'];
import {ReactChild} from 'react';
type extensionProps = Partial<{
customChildren: any;
customChildrenBefore: any;
customChildren: ReactChild | ReactChild[];
customChildrenBefore: ReactChild | ReactChild[];
customCSS: string;
customInnerChildren: any;
customInnerChildren: ReactChild | ReactChild[];
}>;
import {HeaderConnectedProps} from './containers/header';
@ -206,8 +209,9 @@ export type HyperProps = HyperConnectedProps & extensionProps;
import {NotificationsConnectedProps} from './containers/notifications';
export type NotificationsProps = NotificationsConnectedProps & extensionProps;
import Terms from './components/terms';
import {TermsConnectedProps} from './containers/terms';
export type TermsProps = TermsConnectedProps & extensionProps & {ref_: any};
export type TermsProps = TermsConnectedProps & extensionProps & {ref_: (terms: Terms | null) => void};
export type StyleSheetProps = {
backgroundColor: string;
@ -270,7 +274,7 @@ export type TermGroupOwnProps = {
cursorAccentColor?: string;
fontSmoothing?: string;
parentProps: TermsProps;
ref_: (uid: string, term: Term) => void;
ref_: (uid: string, term: Term | null) => void;
termGroup: Immutable<ITermGroup>;
terms: Record<string, Term | null>;
} & Pick<
@ -354,7 +358,7 @@ export type TermProps = {
onActive: () => void;
onContextMenu: (selection: any) => void;
onCursorMove?: (cursorFrame: {x: number; y: number; width: number; height: number; col: number; row: number}) => void;
onData: (data: any) => void;
onData: (data: string) => void;
onResize: (cols: number, rows: number) => void;
onTitle: (title: string) => void;
padding: string;
@ -371,6 +375,7 @@ export type TermProps = {
url: string | null;
webGLRenderer: boolean;
webLinksActivationKey: string;
} & extensionProps & {ref_?: any};
ref_: (uid: string, term: Term | null) => void;
} & extensionProps;
export type Assignable<T, U> = {[k in keyof U]: k extends keyof T ? T[k] : U[k]} & Partial<T>;

View file

@ -76,7 +76,7 @@ rpc.on('session add', (data) => {
store_.dispatch(sessionActions.addSession(data));
});
rpc.on('session data', (d) => {
rpc.on('session data', (d: string) => {
// the uid is a uuid v4 so it's 36 chars long
const uid = d.slice(0, 36);
const data = d.slice(36);

View file

@ -46,7 +46,7 @@ const setActiveGroup = (state: ImmutableType<ITermState>, action: {uid: string})
};
// Reduce existing sizes to fit a new split:
const insertRebalance = (oldSizes: ImmutableType<number[]>, index: any) => {
const insertRebalance = (oldSizes: ImmutableType<number[]>, index: number) => {
const newSize = 1 / (oldSizes.length + 1);
// We spread out how much each pane should be reduced
// with based on their existing size:
@ -167,7 +167,7 @@ const removeGroup = (state: ImmutableType<ITermState>, uid: string) => {
// it's safe to remove the group.
if (group.parentUid && state.termGroups[group.parentUid]) {
const parent = state.termGroups[group.parentUid];
const newChildren = parent.children.filter((childUid: any) => childUid !== uid);
const newChildren = parent.children.filter((childUid) => childUid !== uid);
if (newChildren.length === 1) {
// Since we only have one child left,
// we can merge the parent and child into one group:
@ -188,7 +188,7 @@ const removeGroup = (state: ImmutableType<ITermState>, uid: string) => {
.set('activeSessions', state.activeSessions.without(uid));
};
const resizeGroup = (state: ImmutableType<ITermState>, uid: any, sizes: number[]) => {
const resizeGroup = (state: ImmutableType<ITermState>, uid: string, sizes: number[]) => {
// Make sure none of the sizes fall below MIN_SIZE:
if (sizes.find((size) => size < MIN_SIZE)) {
return state;

View file

@ -1,5 +1,5 @@
/* eslint no-new:0 */
export default function notify(title: string, body: string, details: Record<string, any> = {}) {
export default function notify(title: string, body: string, details: {error?: any} = {}) {
console.log(`[Notification] ${title}: ${body}`);
if (details.error) {
console.error(details.error);