Skip to content

Commit 444bd02

Browse files
TreeView: improve TS typing (DevExpress#30600) (DevExpress#30628)
1 parent 79a1791 commit 444bd02

39 files changed

+1118
-705
lines changed

packages/devextreme/js/__internal/core/widget/component.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ import type { EventInfo, InitializedEventInfo } from '@js/events';
2323

2424
import type { OptionChanged } from './types';
2525

26-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @stylistic/max-len
27-
const getEventName = (actionName): string => actionName.charAt(2).toLowerCase() + actionName.substr(3);
26+
const getEventName = (
27+
actionName: string,
28+
): string => actionName.charAt(2).toLowerCase() + actionName.substr(3);
2829

29-
const isInnerOption = (optionName): boolean => optionName.indexOf('_', 0) === 0;
30+
const isInnerOption = (
31+
optionName: string,
32+
): boolean => optionName.indexOf('_', 0) === 0;
3033

3134
export interface ActionConfig {
3235
beforeExecute?: (e: Record<string, unknown>) => void;
@@ -50,7 +53,7 @@ export interface Properties<TComponent> extends ComponentOptions<
5053

5154
export class Component<
5255
TComponent extends Component<TComponent, TProperties>,
53-
TProperties extends Properties<TComponent>,
56+
TProperties extends Properties<TComponent> = Properties<TComponent>,
5457
// @ts-expect-error dxClass inheritance issue
5558
> extends (Class.inherit({}) as new() => {}) implements PublicComponent<TProperties> {
5659
_deprecatedOptions!: Partial<TProperties>;
@@ -375,7 +378,7 @@ export class Component<
375378
_createActionByOption(
376379
optionName: string,
377380
config?: ActionConfig,
378-
): (event?: Record<string, unknown>) => void {
381+
): (event?: unknown) => void {
379382
// eslint-disable-next-line @typescript-eslint/init-declarations
380383
let action;
381384
// eslint-disable-next-line @typescript-eslint/init-declarations
@@ -418,9 +421,7 @@ export class Component<
418421
const { beforeExecute } = config;
419422
// @ts-expect-error
420423
config.beforeExecute = (...props): void => {
421-
// eslint-disable-next-line @stylistic/max-len
422-
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain, @typescript-eslint/no-unused-expressions
423-
beforeExecute && beforeExecute.apply(this, props);
424+
beforeExecute?.apply(this, props);
424425
this._eventsStrategy.fireEvent(eventName, props[0].args);
425426
};
426427
action = this._createAction(actionFunc, config);
@@ -465,7 +466,7 @@ export class Component<
465466
hasActionSubscription(actionName: string): boolean {
466467
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
467468
return !!this._options.silent(actionName)
468-
|| this._eventsStrategy.hasEvent(getEventName(actionName));
469+
|| this._eventsStrategy.hasEvent(getEventName(actionName));
469470
}
470471

471472
isOptionDeprecated(name: string): boolean {

packages/devextreme/js/__internal/core/widget/dom_component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class DOMComponent<
5656

5757
// eslint-disable-next-line @stylistic/max-len
5858
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
59-
static getInstance(element) {
59+
static getInstance(element: Element | dxElementWrapper) {
6060
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
6161
return getInstanceByElement($(element), this);
6262
}

packages/devextreme/js/__internal/core/widget/widget.ts

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { compare as compareVersions } from '@js/core/utils/version';
1919
import type { DxEvent } from '@js/events';
2020
import { focusable as focusableSelector } from '@js/ui/widget/selectors';
2121
import type { WidgetOptions } from '@js/ui/widget/ui.widget';
22+
import type { KeyboardKeyDownEvent } from '@ts/events/core/m_keyboard_processor';
2223

2324
import DOMComponent from './dom_component';
2425
import type { OptionChanged } from './types';
@@ -29,19 +30,32 @@ export const FOCUSED_STATE_CLASS = 'dx-state-focused';
2930
export const HOVER_STATE_CLASS = 'dx-state-hover';
3031
const INVISIBLE_STATE_CLASS = 'dx-state-invisible';
3132

32-
function setAttribute(name, value, target): void {
33-
// eslint-disable-next-line no-param-reassign
34-
name = name === 'role' || name === 'id' ? name : `aria-${name}`;
35-
// eslint-disable-next-line no-param-reassign
36-
value = isDefined(value) ? value.toString() : null;
37-
38-
target.attr(name, value);
33+
export type SupportedKeyHandler = (
34+
e: DxEvent<KeyboardEvent>,
35+
options?: KeyboardKeyDownEvent
36+
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
37+
) => void | boolean;
38+
export type SupportedKeys = Record<
39+
string,
40+
SupportedKeyHandler
41+
>;
42+
43+
function setAttribute(
44+
name: string,
45+
value: string | undefined | null,
46+
$target: dxElementWrapper,
47+
): void {
48+
const attributeName = name === 'role' || name === 'id' ? name : `aria-${name}`;
49+
50+
const attr = isDefined(value) ? value.toString() : null;
51+
52+
$target.attr(attributeName, attr);
3953
}
4054

4155
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4256
export interface Properties<TComponent = any> extends WidgetOptions<TComponent> {
4357
useResizeObserver?: boolean;
44-
onKeyboardHandled?: (event: KeyboardEvent) => void;
58+
onKeyboardHandled?: (event: KeyboardKeyDownEvent) => void;
4559
isActive?: boolean;
4660
ignoreParentReadOnly?: boolean;
4761
hoveredElement?: dxElementWrapper;
@@ -77,9 +91,8 @@ class Widget<
7791
return options;
7892
}
7993

80-
_supportedKeys():
81-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
82-
Record<string, (e: KeyboardEvent, options?: Record<string, unknown>) => void | boolean> {
94+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
95+
_supportedKeys(e?: DxEvent<KeyboardEvent>): SupportedKeys {
8396
return {};
8497
}
8598

@@ -366,16 +379,14 @@ class Widget<
366379
this._keyboardListenerId = keyboard.on(
367380
this._keyboardEventBindingTarget(),
368381
this._focusTarget(),
369-
(opts) => this._keyboardHandler(opts),
382+
(opts: KeyboardKeyDownEvent) => this._keyboardHandler(opts),
370383
);
371384
}
372385
}
373386

374-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
375-
_keyboardHandler(options, onlyChildProcessing?: boolean): boolean {
387+
_keyboardHandler(options: KeyboardKeyDownEvent, onlyChildProcessing?: boolean): boolean {
376388
if (!onlyChildProcessing) {
377389
const { originalEvent, keyName, which } = options;
378-
// @ts-expect-error
379390
const keys = this._supportedKeys(originalEvent);
380391
const func = keys[keyName] || keys[which];
381392

@@ -678,14 +689,16 @@ class Widget<
678689
focus.trigger(this._focusTarget());
679690
}
680691

681-
registerKeyHandler(key: string, handler: (event?) => void): void {
692+
registerKeyHandler(
693+
key: string,
694+
handler: SupportedKeyHandler,
695+
): void {
682696
const currentKeys = this._supportedKeys();
683697

684-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
685-
this._supportedKeys = (): Record<string, (e) => boolean> => extend(
686-
currentKeys,
687-
{ [key]: handler },
688-
);
698+
this._supportedKeys = (): SupportedKeys => ({
699+
...currentKeys,
700+
[key]: handler,
701+
});
689702
}
690703
}
691704

packages/devextreme/js/__internal/events/core/m_keyboard_processor.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,28 @@ import eventsEngine from '@js/common/core/events/core/events_engine';
22
import { addNamespace, normalizeKeyName } from '@js/common/core/events/utils/index';
33
import Class from '@js/core/class';
44
import $ from '@js/core/renderer';
5+
import type { DxEvent } from '@js/events';
56

67
const COMPOSITION_START_EVENT = 'compositionstart';
78
const COMPOSITION_END_EVENT = 'compositionend';
89
const KEYDOWN_EVENT = 'keydown';
910
const NAMESPACE = 'KeyboardProcessor';
1011

11-
const createKeyDownOptions = (e) => ({
12+
export interface KeyboardKeyDownEvent {
13+
keyName: string;
14+
key: string;
15+
code: string;
16+
ctrl: boolean;
17+
location: number;
18+
metaKey: boolean;
19+
shift: boolean;
20+
alt: boolean;
21+
which: number;
22+
originalEvent: DxEvent<KeyboardEvent>;
23+
}
24+
25+
const createKeyDownOptions = (e: DxEvent<KeyboardEvent>): KeyboardKeyDownEvent => ({
26+
// @ts-expect-error
1227
keyName: normalizeKeyName(e),
1328
key: e.key,
1429
code: e.code,
@@ -37,10 +52,14 @@ const KeyboardProcessor = Class.inherit({
3752
this._handler = options.handler;
3853

3954
if (this._element) {
40-
this._processFunction = (e) => {
55+
this._processFunction = (e: DxEvent<KeyboardEvent>): void => {
4156
const focusTargets = $(this._focusTarget).toArray();
42-
const isNotFocusTarget = this._focusTarget && this._focusTarget !== e.target && !focusTargets.includes(e.target);
43-
const shouldSkipProcessing = this._isComposingJustFinished && e.which === 229 || this._isComposing || isNotFocusTarget;
57+
const isNotFocusTarget = this._focusTarget
58+
&& this._focusTarget !== e.target
59+
&& !focusTargets.includes(e.target);
60+
const shouldSkipProcessing = (this._isComposingJustFinished && e.which === 229)
61+
|| this._isComposing
62+
|| isNotFocusTarget;
4463

4564
this._isComposingJustFinished = false;
4665
if (!shouldSkipProcessing) {
@@ -65,7 +84,7 @@ const KeyboardProcessor = Class.inherit({
6584
this._handler = undefined;
6685
},
6786

68-
process(e) {
87+
process(e: DxEvent<KeyboardEvent>) {
6988
this._handler(createKeyDownOptions(e));
7089
},
7190

packages/devextreme/js/__internal/ui/accordion.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ import { getImageContainer } from '@js/core/utils/icon';
1717
import * as iteratorUtils from '@js/core/utils/iterator';
1818
import { getHeight, getOuterHeight, setHeight } from '@js/core/utils/size';
1919
import { isDefined, isPlainObject } from '@js/core/utils/type';
20-
import type { DxEvent, ItemInfo } from '@js/events';
20+
import type { DxEvent } from '@js/events';
2121
import type { Item, Properties } from '@js/ui/accordion';
2222
import { isMaterialBased } from '@js/ui/themes';
2323
import type { OptionChanged } from '@ts/core/widget/types';
24-
import type { ItemRenderInfo } from '@ts/ui/collection/collection_widget.base';
24+
import type { CollectionItemInfo, ItemRenderInfo } from '@ts/ui/collection/collection_widget.base';
2525
import CollectionWidget from '@ts/ui/collection/collection_widget.live_update';
2626

2727
const ACCORDION_CLASS = 'dx-accordion';
@@ -41,7 +41,7 @@ export interface AccordionProperties extends Properties<Item> {
4141
templatesRenderAsynchronously?: boolean;
4242
}
4343

44-
class Accordion extends CollectionWidget<AccordionProperties> {
44+
class Accordion extends CollectionWidget<AccordionProperties, Item> {
4545
_deferredAnimate?: DeferredObj<unknown>;
4646

4747
// eslint-disable-next-line no-restricted-globals
@@ -183,7 +183,7 @@ class Accordion extends CollectionWidget<AccordionProperties> {
183183
// @ts-expect-error ts-error
184184
const itemData = $(target).parent().data(this._itemDataKey()) as Item | undefined;
185185

186-
return itemData ?? super._getItemData(target) as Item;
186+
return itemData ?? super._getItemData(target);
187187
}
188188

189189
_itemSelectHandler(e: DxEvent): void {
@@ -196,7 +196,7 @@ class Accordion extends CollectionWidget<AccordionProperties> {
196196

197197
_afterItemElementDeleted(
198198
$item: dxElementWrapper,
199-
deletedActionArgs: ItemInfo<Item>,
199+
deletedActionArgs: CollectionItemInfo<Item, number>,
200200
): void {
201201
this._deferredItems.splice(deletedActionArgs.itemIndex, 1);
202202
super._afterItemElementDeleted($item, deletedActionArgs);

packages/devextreme/js/__internal/ui/button_group.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class ButtonCollection extends CollectionWidgetEdit<ButtonCollectionProperties>
135135
return this._focusTarget();
136136
}
137137

138-
_enterKeyHandler(e: KeyboardEvent): void {
138+
_enterKeyHandler(e: DxEvent<KeyboardEvent>): void {
139139
e.preventDefault();
140140
super._enterKeyHandler(e);
141141
}

packages/devextreme/js/__internal/ui/calendar/m_calendar.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { hasWindow } from '@js/core/utils/window';
2525
import Button from '@js/ui/button';
2626
import type { Properties } from '@js/ui/calendar';
2727
import { isFluent } from '@js/ui/themes';
28+
import type { SupportedKeys } from '@ts/core/widget/widget';
2829
import Editor from '@ts/ui/editor/editor';
2930

3031
import CalendarMultipleSelectionStrategy from './m_calendar.multiple.selection.strategy';
@@ -175,7 +176,7 @@ class Calendar<
175176
]);
176177
}
177178

178-
_supportedKeys(): Record<string, (e: KeyboardEvent, options?: Record<string, unknown>) => void> {
179+
_supportedKeys(): SupportedKeys {
179180
return {
180181
...super._supportedKeys(),
181182
rightArrow(e): void {

packages/devextreme/js/__internal/ui/check_box/generated_wrapper.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import registerComponent from '@js/core/component_registrator';
33
import { CheckBox as CheckBoxComponent, defaultOptions } from './check_box';
44
import BaseComponent from './wrapper';
55

6+
// STYLE checkbox
67
export default class CheckBox extends BaseComponent {
78
getProps(): Record<string, unknown> {
89
const props = super.getProps();
@@ -13,13 +14,13 @@ export default class CheckBox extends BaseComponent {
1314

1415
focus(): unknown {
1516
// @ts-expect-error
16-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, prefer-rest-params
17+
// eslint-disable-next-line prefer-rest-params
1718
return this.viewRef?.focus(...arguments);
1819
}
1920

2021
blur(): unknown {
2122
// @ts-expect-error
22-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, prefer-rest-params
23+
// eslint-disable-next-line prefer-rest-params
2324
return this.viewRef?.blur(...arguments);
2425
}
2526

0 commit comments

Comments
 (0)