Using Unions Instead of Base Classes
Inheritance is a part of internal implementation. You should not rely on the knowledge of relationships between base classes and their descendants. For generalization, use a union to define your own type.
For example, if you need a type for properties of multiple editor components, define the following union:
jQuery
type EditorProps = DxTextAreaTypes.Properties | DxTextBoxTypes.Properties | DxAutocompleteTypes.Properties | DxLookupTypes.Properties;
Angular
type EditorProps = DxTextAreaTypes.Properties | DxTextBoxTypes.Properties | DxAutocompleteTypes.Properties | DxLookupTypes.Properties;
Vue
type EditorProps = DxTextAreaTypes.Properties | DxTextBoxTypes.Properties | DxAutocompleteTypes.Properties | DxLookupTypes.Properties;
React
type EditorProps = TextAreaTypes.Properties | TextBoxTypes.Properties | AutocompleteTypes.Properties | LookupTypes.Properties;
Generic Parameters
Some types are generic. This is mostly the case for data-aware component types, such as DataGrid:
Angular
import { Component, ViewChild } from '@angular/core';
import { DxDataGridComponent, DxDataGridTypes } from 'devextreme-angular/ui/data-grid';
import { Employee } from './data';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
@ViewChild(DxDataGridComponent) dataGrid!: DxDataGridComponent<Employee, number>;
onEditorPreparing(e: DxDataGridTypes.EditorPreparingEvent<Employee, number>) {
if (e.dataField === 'LastName' && e.parentType === 'dataRow') {
e.editorOptions.disabled = e.row?.data && e.row?.data.FirstName === '';
}
}
onButtonClick() {
const keys: number[] = this.dataGrid.instance.getSelectedRowKeys();
}
}
<dx-button
text="Get Selected Keys"
(onClick)="onButtonClick()"
>
</dx-button>
<dx-data-grid ...
(onEditorPreparing)="onEditorPreparing($event)"
>
</dx-data-grid>Vue
<template>
<div>
<DxButton
text="Disable DataGrid"
@click="onButtonClick"
/>
<DxDataGrid
:data-source="dataSource"
ref="dataGridRef"
@editor-preparing="onEditorPreparing"
>
</DxDataGrid>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { DxDataGrid } from "devextreme-vue/data-grid";
import { DxButton } from "devextreme-vue/button";
import { type DxDataGridTypes } from "devextreme-vue/data-grid";
import type dxDataGrid from 'devextreme/ui/data_grid';
import { type Employee } from '../data';
const dataGridRef = ref<DxDataGrid>();
function onButtonClick() {
const dataGridInstance: dxDataGrid<Employee, number> = dataGridRef.value?.instance!;
dataGridInstance.option("disabled", true);
}
function onEditorPreparing(e: DxDataGridTypes.EditorPreparingEvent<Employee, number>) {
if (e.dataField === 'LastName' && e.parentType === 'dataRow') {
e.editorOptions.disabled = e.row?.data?.FirstName === '';
}
}
</script>React
import { useRef } from 'react';
import { type Employee, employees as dataSource } from './data';
import DataGrid, { type DataGridTypes, DataGridRef } from 'devextreme-react/data-grid';
import Button from 'devextreme-react/button';
function onEditorPreparing(e: DataGridTypes.EditorPreparingEvent<Employee, number>) {
if (e.dataField === 'LastName' && e.parentType === 'dataRow') {
e.editorOptions.disabled = e.row?.data && e.row?.data.FirstName === '';
}
}
function App() {
const dataGrid = useRef<DataGridRef<Employee, number>>(null);
const onButtonClick = () => {
const dataGridInstance = dataGrid.current!.instance();
dataGridInstance.option("disabled", true);
}
return (
<>
<Button
text={"Disable DataGrid"}
onClick={onButtonClick}
/>
<DataGrid<Employee, number>
ref={dataGrid}
onEditorPreparing={onEditorPreparing}
dataSource={dataSource}>
</DataGrid>
</>
);
}
export default App;Types for Templates
Templates can include complex template data as an argument.
To define types for such templates, import the ComponentTypes declaration and find the type that ends with TemplateData:
import DataGrid, { type DataGridTypes } from 'devextreme-react/data-grid';
import Calendar, { type CalendarTypes } from 'devextreme-react/calendar';
// A rendering function
const gridCell = (data: DataGridTypes.ColumnCellTemplateData) => {
return <span>Custom text</span>;
}
// A component
const CustomCell = ({ data }: { data: CalendarTypes.CellTemplateData }) => {
const { text, view } = data;
return <span>{ text }</span>;
}
export default App() {
return (
<React.Fragment>
<DataGrid>
<Column cellRender={gridCell} />
</DataGrid>
<Calendar cellComponent={CustomCell} />
</React.Fragment>
);
}If you have technical questions, please create a support ticket in the DevExpress Support Center.