Overview
React Hotkeys Hook is written in TypeScript and provides complete type definitions out of the box. You don’t need to install any additional @types packages.
Import Types
All types are exported from the main package:
import {
useHotkeys,
type Options,
type Keys,
type HotkeyCallback,
type HotkeysEvent
} from 'react-hotkeys-hook'
Typed Hook Usage
Basic TypeScript Example
import { useHotkeys } from 'react-hotkeys-hook'
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState<number>(0)
useHotkeys('ctrl+k', () => setCount(prev => prev + 1), [count])
return <div>Count: {count}</div>
}
Typed Callback with Event Parameters
The callback receives strongly-typed parameters:
import { useHotkeys, type HotkeyCallback } from 'react-hotkeys-hook'
const handleHotkey: HotkeyCallback = (event, hotkeysEvent) => {
// event is KeyboardEvent
console.log('Key pressed:', event.key)
console.log('Ctrl pressed:', event.ctrlKey)
// hotkeysEvent is HotkeysEvent with metadata
console.log('Hotkey triggered:', hotkeysEvent.hotkey)
console.log('Keys:', hotkeysEvent.keys)
console.log('Modifiers:', hotkeysEvent.ctrl, hotkeysEvent.shift)
}
useHotkeys('ctrl+s', handleHotkey)
Typed Refs for Focus Trapping
When using focus trapping, specify the element type as a generic parameter:
import { useHotkeys } from 'react-hotkeys-hook'
function FocusedInput() {
// Specify HTMLInputElement for an input
const inputRef = useHotkeys<HTMLInputElement>(
'ctrl+s',
() => console.log('Save from input')
)
return <input ref={inputRef} />
}
function FocusedDiv() {
// Specify HTMLDivElement for a div
const divRef = useHotkeys<HTMLDivElement>(
'escape',
() => console.log('Close')
)
return <div ref={divRef} tabIndex={-1}>Focusable div</div>
}
Generic Types for Different Elements
import { useHotkeys } from 'react-hotkeys-hook'
// Button
const buttonRef = useHotkeys<HTMLButtonElement>('enter', handleSubmit)
// Textarea
const textareaRef = useHotkeys<HTMLTextAreaElement>('ctrl+enter', handleSave)
// Any div or span
const containerRef = useHotkeys<HTMLDivElement>('escape', handleClose)
// Section or article
const sectionRef = useHotkeys<HTMLElement>('n', handleNext)
Typed Options
The Options type provides full IntelliSense for all configuration options:
import { useHotkeys, type Options } from 'react-hotkeys-hook'
const options: Options = {
enabled: true,
preventDefault: true,
enableOnFormTags: ['input', 'textarea'],
description: 'Save the current document',
scopes: ['editor'],
keydown: true,
keyup: false,
}
useHotkeys('ctrl+s', handleSave, options)
The FormTags type ensures you only use valid tag names:
import { useHotkeys, type FormTags, type Options } from 'react-hotkeys-hook'
// Valid form tags
const validTags: readonly FormTags[] = [
'input',
'textarea',
'select',
'searchbox', // ARIA role
'textbox', // ARIA role
]
const options: Options = {
enableOnFormTags: validTags,
}
useHotkeys('ctrl+k', handleCommand, options)
Conditional Trigger Functions
The Trigger type allows boolean or function:
import { useHotkeys, type Trigger, type Options } from 'react-hotkeys-hook'
// As a function
const enabledWhen: Trigger = (keyboardEvent, hotkeysEvent) => {
// Only enable if not in an input field
const target = keyboardEvent.target as HTMLElement
return target.tagName !== 'INPUT'
}
const preventDefaultWhen: Trigger = (keyboardEvent) => {
// Only prevent default for certain keys
return keyboardEvent.key === 's'
}
const options: Options = {
enabled: enabledWhen,
preventDefault: preventDefaultWhen,
}
useHotkeys('ctrl+s', handleSave, options)
Working with Scopes
import { useHotkeysContext, type Scopes } from 'react-hotkeys-hook'
function ScopeManager() {
const { enableScope, disableScope, activeScopes } = useHotkeysContext()
// activeScopes is string[]
const currentScopes: string[] = activeScopes
// Scopes can be string or readonly string[]
const editorScopes: Scopes = ['editor', 'textEdit']
return (
<div>
<p>Active: {currentScopes.join(', ')}</p>
<button onClick={() => enableScope('editor')}>
Enable Editor
</button>
</div>
)
}
Keys Type
The Keys type accepts string or array:
import { useHotkeys, type Keys } from 'react-hotkeys-hook'
// Single key
const singleKey: Keys = 'ctrl+s'
useHotkeys(singleKey, handleSave)
// Multiple keys
const multipleKeys: Keys = ['ctrl+s', 'cmd+s']
useHotkeys(multipleKeys, handleSave)
// Readonly array
const readonlyKeys: readonly string[] = ['a', 'b', 'c'] as const
useHotkeys(readonlyKeys, handleKey)
You can add custom metadata with type safety:
import { useHotkeys, type Options } from 'react-hotkeys-hook'
interface CustomMetadata {
action: string
category: string
icon?: string
}
const options: Options = {
description: 'Open command palette',
metadata: {
action: 'openCommandPalette',
category: 'navigation',
icon: 'command',
} as CustomMetadata,
}
useHotkeys('ctrl+k', handleCommand, options)
Type Inference
TypeScript can often infer types automatically:
import { useHotkeys } from 'react-hotkeys-hook'
// Types are inferred
useHotkeys('ctrl+k', (event, hotkeysEvent) => {
// event: KeyboardEvent (inferred)
// hotkeysEvent: HotkeysEvent (inferred)
console.log(event.key)
console.log(hotkeysEvent.hotkey)
})
// Options are type-checked
useHotkeys('ctrl+s', handleSave, {
enabled: true, // ✓ boolean
preventDefault: true, // ✓ boolean or function
enableOnFormTags: ['input'], // ✓ FormTags[]
keydown: true, // ✓ boolean
})
Common TypeScript Patterns
import { useHotkeys, type HotkeyCallback } from 'react-hotkeys-hook'
const callbacks: Record<string, HotkeyCallback> = {
save: (event) => console.log('Save'),
copy: (event) => console.log('Copy'),
paste: (event) => console.log('Paste'),
}
Object.entries(callbacks).forEach(([key, callback]) => {
useHotkeys(`ctrl+${key[0]}`, callback)
})
Type-Safe Hotkey Registry
import { useHotkeys, type Options } from 'react-hotkeys-hook'
interface HotkeyConfig {
keys: string
description: string
handler: () => void
options?: Options
}
const hotkeys: HotkeyConfig[] = [
{
keys: 'ctrl+s',
description: 'Save document',
handler: () => console.log('Save'),
options: { preventDefault: true },
},
{
keys: 'ctrl+k',
description: 'Open command palette',
handler: () => console.log('Command palette'),
},
]
function useHotkeyRegistry(hotkeys: HotkeyConfig[]) {
hotkeys.forEach(({ keys, handler, options }) => {
useHotkeys(keys, handler, options)
})
}
All types are re-exported from the main package, so you always import from react-hotkeys-hook.
Use TypeScript’s IntelliSense to discover available options and type constraints as you type.