DevExtreme
DevExtreme copied to clipboard
Internal Types
The Problem
We're extending the DevExtreme TypeScript API and adding a lot of new types. To maintain consistency, we are reviewing existing type names and locations. At the same time, we're separating public types from internal ones to protect you from unnecessary breaking changes in the future.
The Solution
We marked a lot of types as deprecated with the following message:
Warning! This type is used for internal purposes. Do not import it directly.
This means that the type is considered to be internal. In some cases, it will be renamed or moved to another module.
We Need Your Feedback
We really need your feedback. If you see that warning message, please specify the type that cause it. We will offer you a suitable replacement.
Which version of DevExtreme has these changes?
We added the @deprecated
tag to these warnings in v21.1. After the upgrade, you can check your console and report to us which types are causing it.
I'm currently développions an Angular + .NET5 solution with DevExtreme 21.2.3 version and I'm finding @deprecated attribute with most of the interface/event/class types that I need to used in my code. I really want to fully use the typing features with intellisense with vscode and angular because I think it's more easy to code and make code expectation more obvious.
I would like to be sure that I can still use the typing with DevExtreme so ti will be appreciated if you can provide a working typing file without @deprecated. Thanks!
For example, I cannot use the LoadOptions:
const customStore = new CustomStore({
load: (loadOptions: DevExpress.data.LoadOptions) => {
If I go to definition to the LoadOptions, this is what I found:
/**
*
* @deprecated Warning! This type is used for internal purposes. Do not import it directly.
*/
export interface LoadOptions {
@SteveLemire, could you give us a complete list of these warnings? It would be helpful if you share a log file. We'll review the types you're using and mark them as public or specify recommended replacements.
@IlyaKhD here is a list of DX deprecated types we have used:
import {isObject} from 'devextreme/core/utils/type';
import {CustomStoreOptions} from 'devextreme/data/custom_store';
import {dxDataGridRowObject} from 'devextreme/ui/data_grid';
import {LoadOptions} from 'devextreme/data/load_options';
import {dxValidatorResult} from 'devextreme/ui/validator';
import {DataSourceOptions} from 'devextreme/data/data_source';
import dxButtonGroupItem = DevExpress.ui.dxButtonGroupItem;
import {dxTextBoxOptions} from 'devextreme/ui/text_box';
import {dxSelectBoxOptions} from 'devextreme/ui/select_box';
import {dxDataGridOptions} from 'devextreme/ui/data_grid';
import {dxGalleryOptions} from 'devextreme/ui/gallery';
import {dxFormOptions} from 'devextreme/ui/form';
import positionConfig = DevExpress.positionConfig;
import devices, {Device} from 'devextreme/core/devices';
Following is not marked as deprecated but you might have forgotten about it:
import {humanize} from 'devextreme/core/utils/inflector';
@SteveLemire, could you give us a complete list of these warnings? It would be helpful if you share a log file. We'll review the types you're using and mark them as public or specify recommended replacements.
@hakimio mentioned most of them.
Im starting the project so I don't have the complete list. I'm coding generic component and they are all auto-generated so most of the code to render devextreme components is done in the code behind and then bind to the html component declaration.
When I use a new devextreme component, I would like to have typing for events, configuration, datasource and other related types to manage the rendering from the code behind.
@IlyaKhD I understand and fully agree that some internal library logic should be kept private, but coming from Sencha ExtJS framework, one thing I miss is a large amount of utility classes available to the user of the framework. Basically, there was almost no reason to install any 3rd party utility library since you already had everything you needed. I think, it might be best that instead of trying to hide as much as you can, you would also consider making public at least some of the DX utility functions you consider stable. If you would add them to your API documentation with some example usage, it would add a lot of value to DX users.
@IlyaKhD, hi!
We're using ColumnCustomizeTextArg
type and it's deprecated now. We're using it for customizeText
function
@hakimio, I think these two options are not exclusive. I mean hiding internal types that are used in Components' property declarations and making utilities public.
We're reviewing internal types to improve the component configuration process, but we're not changing the API. In a general case, no runtime features are made public or private.
Making internal utilities public is a matter of extending the API, not just changing types.
@SteveLemire, @hakimio, @Bykiev thank you for sharing these types lists. Once we have any updates we'll post them here.
Btw, the 21.1.4 update includes a couple of public replacements:
- dxDataGrid
-
Column
instead ofdxDataGridColumn
-
ColumnButton
instead ofdxDataGridColumnButton
-
- dxTreeList
-
Column
instead ofdxDataGridColumn
-
ColumnButton
instead ofdxDataGridColumnButton
-
- dxScheduler
-
Appointment
instead ofdxSchedulerAppointment
-
@IlyaKhD, can you please help me with DevExtreme typings?
I'm using dxTextArea onKeyDown
event, it's type is NativeEventInfo<T>
(NativeEventInfo<dxTextArea>
in my case). I would like to check wich key was pressed, but how to get access to JQuery keyCode
from DX EventObject
?
Also Deffered
is marked as internal, but is used for custom adapter implementation here
allowEditing (as function) and other type definitions is hard to use
/**
* Specifies whether a user can delete rows. It is called for each data row when defined as a function.
*/
allowDeleting?:
| boolean
| ((options: { component?: dxDataGrid; row?: RowObject }) => boolean);
RowObject
type is internal, it'll be better to create EditingObject
interface with component
and row
props
Same here with visible (as function) and many other types where RowObject
is used
import PivotGridDataSource, { PivotGridDataSourceOptions } from 'devextreme/ui/pivot_grid/data_source';
const pivotGridDataSourceOptions: PivotGridDataSourceOptions = {
fields: [{
caption: 'Status',
dataField: 'status',
area: 'row',
//sortBySummaryField: 'Total'
}, {
caption: 'DNSP',
dataField: 'dnsp',
area: 'column'
}, {
caption: 'Total',
dataField: 'deviceId',
dataType: 'string',
summaryType: 'count',
area: 'data'
}],
store: dummyStore
};
const dataSource: PivotGridDataSource = new PivotGridDataSource(pivotGridDataSourceOptions);
Maybe I am missing something out, but we are using the options (like DevExpress.ui.dxTagBoxOptions
) on multiple occasions, e.g. when using TypeMoq for testing:
jQueryMock.verify((mock) => mock.dxTagBox(
TypeMoq.It.is<DevExpress.ui.dxTagBoxOptions>((options) => {
return options.showClearButton === true && options.displayExpr === 'displayValue';
})
), TypeMoq.Times.once());
Is there any way to use this typings in a non-deprecated way? Would I need to use DevExpress.ui.dxTagBox.Properties
instead?
Hi @Bykiev, @iofluxdev1, @Owlbertz,
First of all, I want to thank you for sharing your usage scenarios. This will help us to make our TypeScript definitions better.
As for the questions, let me address them one by one.
@Bykiev
I'm using dxTextArea onKeyDown event, it's type is NativeEventInfo<T> (NativeEventInfo<dxTextArea> in my case). I would like to check wich key was pressed, but how to get access to JQuery keyCode from DX EventObject?
As far as I understand, you are using Angular If you are using a native event, it is unnecessary to get access to the jQuery keyCode. You can use a native keyCode option. However, if your usage scenario is different, I would appreciate it if you describe it and the issue in greater detail.
@Owlbertz
Is there any way to use this typings in a non-deprecated way? Would I need to use DevExpress.ui.dxTagBox.Properties instead?
Currently, we are working on a list of updated typings, but it is not ready yet. So, you can continue using deprecated options. Once updated options are ready, we will publish them and update deprecation messages.
I'm using dxTextArea onKeyDown event, it's type is NativeEventInfo (NativeEventInfo in my case). I would like to check wich key was pressed, but how to get access to JQuery keyCode from DX EventObject?
As far as I understand, you are using Angular If you are using a native event, it is unnecessary to get access to the jQuery keyCode. You can use a native keyCode option. However, if your usage scenario is different, I would appreciate it if you describe it and the issue in greater detail.
@LexDX, thank you for you time and efforts! Do I understand you correctly that I should cast event
property of dxTextArea onValueChanged event to KeyboardEvent or jQuery.Event (if jQuery is used)?
It's not clear for me, as it's defined in DevExtreme typings as DxEvent
which extends EventType
or EventObject
.
Upd: I can't cast it directly neither to KeyboardEvent
nor jQuery.Event
.
Upd2 It seems event typings are wrong, EventType
should extend JQueryEventObject
:
interface EventType extends JQueryEventObject {
cancel?: boolean;
}
I did a PR #18265 for this
Thanks!
Some 'deprecated' imports from me:
import dxScrollable from 'devextreme/ui/scroll_view/ui.scrollable'
dxScrollable.defaultOptions({ // `dxScrollable` marked as deprecated
...
})
import type { PivotGridDataSourceField } from 'devextreme/ui/pivot_grid/data_source'
I use this type for typing fields in PivotGrid.
import type { dxPivotGridPivotGridCell } from 'devextreme/ui/pivot_grid'
I use this type for getting information about the pivot grid cell (for example in functions called inside onCellPrepared
).
import type { ExcelDataGridCell } from 'devextreme/excel_exporter'
import type { ExcelPivotGridCell } from 'devextreme/excel_exporter'
Used in customizeCell
callbacks in custom export.
import type { DeferredObj } from 'devextreme/core/utils/deferred'
...
const tabPanel = tabPanelRef.current?.instance
const deferredItems: DeferredObj<unknown>[] = (tabPanel as any)?._deferredItems ?? []
await Promise.all(deferredItems.map((deferredItem) => deferredItem.resolve()))
In some cases (before export for example) I need preload tab contents.
As I wrote in my post earlier, I'm generating grid and form in the code-behind. During this process, I have to create form items but there is no "form item types" so I had to create dxFormItemTypes and dxFormSimpleItemEditorTypes like this:
import {
dxFormButtonItem,
dxFormEmptyItem,
dxFormGroupItem,
dxFormSimpleItem,
dxFormTabbedItem,
} from 'devextreme/ui/form';
export type dxFormItemTypes =
| dxFormSimpleItem
| dxFormGroupItem
| dxFormTabbedItem
| dxFormEmptyItem
| dxFormButtonItem;
export type dxFormSimpleItemEditorTypes =
| 'dxAutocomplete'
| 'dxCalendar'
| 'dxCheckBox'
| 'dxColorBox'
| 'dxDateBox'
| 'dxDropDownBox'
| 'dxHtmlEditor'
| 'dxLookup'
| 'dxNumberBox'
| 'dxRadioGroup'
| 'dxRangeSlider'
| 'dxSelectBox'
| 'dxSlider'
| 'dxSwitch'
| 'dxTagBox'
| 'dxTextArea'
| 'dxTextBox';
I'm wondering why these "types" are not available from Devexpress library?
Why is this deprecated?
export interface RemoteFileSystemProviderOptions extends FileSystemProviderBaseOptions<RemoteFileSystemProvider> {
/**
* Specifies a function that customizes an Ajax request before it is sent to the server.
*/
beforeAjaxSend?: ((options: { headers?: any, xhrFields?: any, formData?: any }) => void);
/**
* Specifies a function that customizes a form submit request before it is sent to the server.
*/
beforeSubmit?: ((options: { formData?: any }) => void);
/**
* Specifies the URL of an endpoint used to access and modify a file system located on the server.
*/
endpointUrl?: string;
/**
* Specifies which data field provides information about whether a directory has subdirectories.
*/
hasSubDirectoriesExpr?: string | Function;
/**
* Specifies the request headers.
*/
requestHeaders?: any;
}
I'm also having problems with requestHeaders
, once specified a few default headers are no longer sent (e.g.: Origin which is used by CORS).
Hi, guys. Tell me please, what I can use instead of import { Summary } from 'devextreme/ui/data_grid'
?
Hi @all,
Thank you for your continuous feedback.
@Bykiev,
Yes, I see the issue now. We did not include the native event in Angular typings. So, there is no way to use this event in the current version. As a temporary workaround, you can cast the e.event
object to any
. Then, use originalEvent and cast it to KeyboardEvent:
const evt = (e.event as any).originalEvent as KeyboardEvent;
Regarding your pull request, let me share more information about our TypeScript changes. We do not have plans to make the same jQuery typings for all frameworks. Our main goal is to create a set of typings that will be useful in the current framework. So, we did not include jQuery typings by default. However, the lack of native events causes issues, so we will discuss adding the missing options.
@Semigradsky, thank you for sharing your typings.
@SteveLemire,
We just started extending our typings and rewriting our TypeScript definitions. The work is not finished yet, so you can expect changes in next releases. We will take your usage scenario into account.
@R4DIC4L,
We deprecated all TypeScript definitions as we did not have any public types yet. In this GitHub issue, we collect main use cases so that we can update our typings and make them public later.
Regarding the issue with request headers, please submit a ticket to our Support Center - https://www.devexpress.com/ask. In the ticket, please share more details and a sample project. Our team will analyze and debug it. This will help us find a precise solution for you.
@AChelp,
Currently, we do not have an alternative. Once we add it, we will update deprecation messages with the required information so that you will be able to migrate to correct typings.
@LexDX, thank you for your comments! But I still don't understand the puprpose of extending DxEvent
with an EventType
interface, which extends empty interface JQueryEventObject
, also there is a comment here:
/**
* @docid
* @type EventObject|jQuery.Event
*/
So, DxEvent
should extend EventObject
or jQuery.Event
(if jQuery is used) or JQueryEventObject
should extend jQuery.Event
There is some more issues with two-way binding in Angular, I've already described it here
Thanks @LexDX to give us all these feedbacks, it's really appreciated.
Devextreme is a very nice productivity components framework and I want to use the Type script features in the frontend the same way I do in the backend C# .net5 server.
Instead of anonymous typing (like javascript), I want to use typing as much as I can so all developers are aware of the in/out properties/methods. As you know, the latest version of typescript is becoming more strict for all theses reasons. That's the main purpose of using TypeScript!!!
Maybe I'm wrong by generating UI/UX in the code behind but I think it's best way to get the power of customizations with my code that creates responsive grids and forms.
By the way, I just bought your latest Devetreme version 21.1.4 and upgraded to latest Angular 12.1.1 and everything works fine so nice job to all your teams!!!!
Thanks again!!
dxToolbarItem
https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxToolbar/Configuration/items/
Can we get everything in your documentation that refers to a type to be available? Ideally if you can keep the names referred to your documentation to avoid us having a considerable amount of tech debt across our apps would be appreciated.
Hi @all,
@Bykiev,
But I still don't understand the purpose of extending DxEvent with an EventType interface, which extends empty interface JQueryEventObject
We use the built-in jQuery JQueryEventObject when jQuery is enabled in the application. For the situation when there is no jQuery in the application, we use an empty interface to avoid compilation issues.
So, DxEvent should extend EventObject or jQuery.Event (if jQuery is used) or JQueryEventObject should extend jQuery.Event
The main reason why our event types are created in this way is related to the fact that not all applications have jQuery integration. So, to avoid creating two sets of typings, we used a different solution. However, the documentation shows the information about real event types.
There is some more issues with two-way binding in Angular, I've already described it here
Thank you for the information. I'll check the issue and reply to you in the initial thread once I have any news.
@SteveLemire,
Thank you for the detailed explanation. I think I got your point and I shared it with our team.
@mtopp7,
We have plans to update our documentation once we finish our new typings. So, we'll make these new TypeScript definitions public and documented.
import { dxTabPanelItem } from 'devextreme/ui/tab_panel';
dxTabPanelItem
marked as deprecated, used as a dataSource for tabPanel
control
We are using dxForm*Item
(e.g. dxFormSimpleItem
) to create form items in separate locations from where they are actually added to the form.
I want to iterate over all visible rows of my TreeList when the drag starts:
How can I do that in a strongly typed manner?
@davidich they have deprecated everything but haven't introduced replacements yet...
I am currently using this:
import { dxDataGridSelection, dxDataGridScrolling } from 'devextreme/ui/data_grid';
I am using a custom control to deal with selection of rows, and I need the type to be able to pass the selection props that were supplied to the grid down to my custom component.
Similar reasons for the dxDataGridScrolling also, I need to pass the prop values around and need the type.