提交 99ab1d7a 编写于 作者: 1 100pah

ts: (1) add more strict type check for id, name from option. (2) add more...

ts: (1) add more strict type check for id, name from option. (2) add more strict conversion for id, name from option.
上级 85a47ef6
...@@ -30,6 +30,7 @@ import { ...@@ -30,6 +30,7 @@ import {
OptionDataItemObject OptionDataItemObject
} from '../../util/types'; } from '../../util/types';
import SeriesModel from '../../model/Series'; import SeriesModel from '../../model/Series';
import { convertOptionIdName } from '../../util/model';
export default function ( export default function (
nodes: OptionSourceDataOriginal<OptionDataValue, OptionDataItemObject<OptionDataValue>>, nodes: OptionSourceDataOriginal<OptionDataValue, OptionDataItemObject<OptionDataValue>>,
...@@ -59,7 +60,7 @@ export default function ( ...@@ -59,7 +60,7 @@ export default function (
if (graph.addEdge(source, target, linkCount)) { if (graph.addEdge(source, target, linkCount)) {
validEdges.push(link); validEdges.push(link);
linkNameList.push(zrUtil.retrieve( linkNameList.push(zrUtil.retrieve(
link.id != null ? link.id + '' : null, convertOptionIdName(link.id, null),
source + ' > ' + target source + ' > ' + target
)); ));
linkCount++; linkCount++;
......
...@@ -25,7 +25,6 @@ import type { SeriesOption, SeriesOnCartesianOptionMixin, LayoutOrient } from '. ...@@ -25,7 +25,6 @@ import type { SeriesOption, SeriesOnCartesianOptionMixin, LayoutOrient } from '.
import type GlobalModel from '../../model/Global'; import type GlobalModel from '../../model/Global';
import type SeriesModel from '../../model/Series'; import type SeriesModel from '../../model/Series';
import type CartesianAxisModel from '../../coord/cartesian/AxisModel'; import type CartesianAxisModel from '../../coord/cartesian/AxisModel';
import type DataDimensionInfo from '../../data/DataDimensionInfo';
import type List from '../../data/List'; import type List from '../../data/List';
import type Axis2D from '../../coord/cartesian/Axis2D'; import type Axis2D from '../../coord/cartesian/Axis2D';
import { CoordDimensionDefinition } from '../../data/helper/createDimensions'; import { CoordDimensionDefinition } from '../../data/helper/createDimensions';
......
...@@ -38,7 +38,7 @@ import GlobalModel from '../../model/Global'; ...@@ -38,7 +38,7 @@ import GlobalModel from '../../model/Global';
import List from '../../data/List'; import List from '../../data/List';
import { LayoutRect } from '../../util/layout'; import { LayoutRect } from '../../util/layout';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup'; import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
import { defaultSeriesFormatTooltip } from '../../component/tooltip/seriesFormatTooltip';
type FocusNodeAdjacency = boolean | 'inEdges' | 'outEdges' | 'allEdges'; type FocusNodeAdjacency = boolean | 'inEdges' | 'outEdges' | 'allEdges';
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
import ComponentModel from '../../model/Component'; import ComponentModel from '../../model/Component';
import List from '../../data/List'; import List from '../../data/List';
import * as modelUtil from '../../util/model';
import { import {
ComponentOption, ComponentOption,
BoxLayoutOptionMixin, BoxLayoutOptionMixin,
...@@ -38,6 +37,7 @@ import { ...@@ -38,6 +37,7 @@ import {
import Model from '../../model/Model'; import Model from '../../model/Model';
import GlobalModel, { GlobalModelSetOptionOpts } from '../../model/Global'; import GlobalModel, { GlobalModelSetOptionOpts } from '../../model/Global';
import { each, isObject, clone, isString } from 'zrender/src/core/util'; import { each, isObject, clone, isString } from 'zrender/src/core/util';
import { convertOptionIdName, getDataItemValue } from '../../util/model';
export interface TimelineControlStyle extends ItemStyleOption { export interface TimelineControlStyle extends ItemStyleOption {
...@@ -247,7 +247,7 @@ class TimelineModel extends ComponentModel<TimelineOption> { ...@@ -247,7 +247,7 @@ class TimelineModel extends ComponentModel<TimelineOption> {
if (axisType === 'category') { if (axisType === 'category') {
processedDataArr = []; processedDataArr = [];
each(dataArr, function (item, index) { each(dataArr, function (item, index) {
let value = modelUtil.getDataItemValue(item); const value = convertOptionIdName(getDataItemValue(item), '');
let newItem; let newItem;
if (isObject(item)) { if (isObject(item)) {
...@@ -260,11 +260,7 @@ class TimelineModel extends ComponentModel<TimelineOption> { ...@@ -260,11 +260,7 @@ class TimelineModel extends ComponentModel<TimelineOption> {
processedDataArr.push(newItem); processedDataArr.push(newItem);
if (!isString(value) && (value == null || isNaN(value as number))) { names.push(value);
value = '';
}
names.push(value + '');
}); });
} }
else { else {
......
...@@ -33,9 +33,10 @@ import {ArrayLike, Dictionary, FunctionPropertyNames} from 'zrender/src/core/typ ...@@ -33,9 +33,10 @@ import {ArrayLike, Dictionary, FunctionPropertyNames} from 'zrender/src/core/typ
import Element from 'zrender/src/Element'; import Element from 'zrender/src/Element';
import { import {
DimensionIndex, DimensionName, DimensionLoose, OptionDataItem, DimensionIndex, DimensionName, DimensionLoose, OptionDataItem,
ParsedValue, ParsedValueNumeric, OrdinalNumber, DimensionUserOuput, ModelOption, SeriesDataType ParsedValue, ParsedValueNumeric, OrdinalNumber, DimensionUserOuput,
ModelOption, SeriesDataType, OrdinalRawValue
} from '../util/types'; } from '../util/types';
import {isDataItemOption} from '../util/model'; import {isDataItemOption, convertOptionIdName} from '../util/model';
import { getECData } from '../util/ecData'; import { getECData } from '../util/ecData';
import { PathStyleProps } from 'zrender/src/graphic/Path'; import { PathStyleProps } from 'zrender/src/graphic/Path';
import type Graph from './Graph'; import type Graph from './Graph';
...@@ -144,12 +145,21 @@ export interface DefaultDataVisual { ...@@ -144,12 +145,21 @@ export interface DefaultDataVisual {
colorFromPalette?: boolean colorFromPalette?: boolean
} }
export interface DataCalculationInfo<SERIES_MODEL> {
stackedDimension: string;
stackedByDimension: string;
isStackedByIndex: boolean;
stackedOverDimension: string;
stackResultDimension: string;
stackedOnSeries?: SERIES_MODEL;
}
// ----------------------------- // -----------------------------
// Internal method declarations: // Internal method declarations:
// ----------------------------- // -----------------------------
let defaultDimValueGetters: {[sourceFormat: string]: DimValueGetter}; let defaultDimValueGetters: {[sourceFormat: string]: DimValueGetter};
let prepareInvertedIndex: (list: List) => void; let prepareInvertedIndex: (list: List) => void;
let getRawValueFromStore: (list: List, dimIndex: number, rawIndex: number) => any; let getRawValueFromStore: (list: List, dimIndex: number, rawIndex: number) => ParsedValue | OrdinalRawValue;
let getIndicesCtor: (list: List) => DataArrayLikeConstructor; let getIndicesCtor: (list: List) => DataArrayLikeConstructor;
let prepareChunks: ( let prepareChunks: (
storage: DataStorage, dimInfo: DataDimensionInfo, chunkSize: number, chunkCount: number, end: number storage: DataStorage, dimInfo: DataDimensionInfo, chunkSize: number, chunkCount: number, end: number
...@@ -245,7 +255,7 @@ class List< ...@@ -245,7 +255,7 @@ class List<
private _invertedIndicesMap: {[dimName: string]: ArrayLike<number>}; private _invertedIndicesMap: {[dimName: string]: ArrayLike<number>};
private _calculationInfo: {[key: string]: any} = {}; private _calculationInfo: DataCalculationInfo<HostModel> = {} as DataCalculationInfo<HostModel>;
// User output info of this data. // User output info of this data.
// DO NOT use it in other places! // DO NOT use it in other places!
...@@ -628,7 +638,7 @@ class List< ...@@ -628,7 +638,7 @@ class List<
// ??? FIXME not check by pure but sourceFormat? // ??? FIXME not check by pure but sourceFormat?
// TODO refactor these logic. // TODO refactor these logic.
if (!rawData.pure) { if (!rawData.pure) {
let name: any = nameList[idx]; let name: string = nameList[idx];
if (dataItem && name == null) { if (dataItem && name == null) {
// If dataItem is {name: ...}, it has highest priority. // If dataItem is {name: ...}, it has highest priority.
...@@ -636,24 +646,26 @@ class List< ...@@ -636,24 +646,26 @@ class List<
if ((dataItem as any).name != null) { if ((dataItem as any).name != null) {
// There is no other place to persistent dataItem.name, // There is no other place to persistent dataItem.name,
// so save it to nameList. // so save it to nameList.
nameList[idx] = name = (dataItem as any).name; nameList[idx] = name = convertOptionIdName((dataItem as any).name, null);
} }
else if (nameDimIdx != null) { else if (nameDimIdx != null) {
const nameDim = dimensions[nameDimIdx]; const nameDim = dimensions[nameDimIdx];
const nameDimChunk = storage[nameDim][chunkIndex]; const nameDimChunk = storage[nameDim][chunkIndex];
if (nameDimChunk) { if (nameDimChunk) {
name = nameDimChunk[chunkOffset];
const ordinalMeta = dimensionInfoMap[nameDim].ordinalMeta; const ordinalMeta = dimensionInfoMap[nameDim].ordinalMeta;
if (ordinalMeta && ordinalMeta.categories.length) { name = convertOptionIdName(
name = ordinalMeta.categories[name]; (ordinalMeta && ordinalMeta.categories.length)
} ? ordinalMeta.categories[nameDimChunk[chunkOffset] as number]
: nameDimChunk[chunkOffset],
null
);
} }
} }
} }
// Try using the id in option // Try using the id in option
// id or name is used on dynamical data, mapping old and new items. // id or name is used on dynamical data, mapping old and new items.
let id = dataItem == null ? null : (dataItem as any).id; let id: string = dataItem == null ? null : convertOptionIdName((dataItem as any).id, null);
if (id == null && name != null) { if (id == null && name != null) {
// Use name as id and add counter to avoid same name // Use name as id and add counter to avoid same name
...@@ -908,17 +920,29 @@ class List< ...@@ -908,17 +920,29 @@ class List<
this._approximateExtent[dim] = extent.slice() as [number, number]; this._approximateExtent[dim] = extent.slice() as [number, number];
} }
getCalculationInfo(key: string): any { getCalculationInfo<CALC_INFO_KEY extends keyof DataCalculationInfo<HostModel>>(
key: CALC_INFO_KEY
): DataCalculationInfo<HostModel>[CALC_INFO_KEY] {
return this._calculationInfo[key]; return this._calculationInfo[key];
} }
/** /**
* @param key or k-v object * @param key or k-v object
*/ */
setCalculationInfo(key: string | object, value?: any) { setCalculationInfo(
key: DataCalculationInfo<HostModel>
): void;
setCalculationInfo<CALC_INFO_KEY extends keyof DataCalculationInfo<HostModel>>(
key: CALC_INFO_KEY,
value: DataCalculationInfo<HostModel>[CALC_INFO_KEY]
): void;
setCalculationInfo(
key: (keyof DataCalculationInfo<HostModel>) | DataCalculationInfo<HostModel>,
value?: DataCalculationInfo<HostModel>[keyof DataCalculationInfo<HostModel>]
): void {
isObject(key) isObject(key)
? zrUtil.extend(this._calculationInfo, key as object) ? zrUtil.extend(this._calculationInfo, key as object)
: (this._calculationInfo[key] = value); : ((this._calculationInfo as any)[key] = value);
} }
/** /**
...@@ -1140,13 +1164,25 @@ class List< ...@@ -1140,13 +1164,25 @@ class List<
} }
} }
/**
* @return Never be null/undefined. `number` will be converted to string. Becuase:
* In most cases, name is used in display, where returning a string is more convenient.
* In other cases, name is used in query (see `indexOfName`), where we can keep the
* rule that name `2` equals to name `'2'`.
*/
getName(idx: number): string { getName(idx: number): string {
const rawIndex = this.getRawIndex(idx); const rawIndex = this.getRawIndex(idx);
return this._nameList[rawIndex] return this._nameList[rawIndex]
|| getRawValueFromStore(this, this._nameDimIdx, rawIndex) || convertOptionIdName(getRawValueFromStore(this, this._nameDimIdx, rawIndex), '')
|| ''; || '';
} }
/**
* @return Never null/undefined. `number` will be converted to string. Becuase:
* In all cases having encountered at present, id is used in making diff comparison, which
* are usually based on hash map. We can keep the rule that the internal id are always string
* (treat `2` is the same as `'2'`) to make the related logic simple.
*/
getId(idx: number): string { getId(idx: number): string {
return getId(this, this.getRawIndex(idx)); return getId(this, this.getRawIndex(idx));
} }
...@@ -1981,7 +2017,9 @@ class List< ...@@ -1981,7 +2017,9 @@ class List<
}); });
}; };
getRawValueFromStore = function (list: List, dimIndex: number, rawIndex: number): any { getRawValueFromStore = function (
list: List, dimIndex: number, rawIndex: number
): ParsedValue | OrdinalRawValue {
let val; let val;
if (dimIndex != null) { if (dimIndex != null) {
const chunkSize = list._chunkSize; const chunkSize = list._chunkSize;
...@@ -2043,10 +2081,13 @@ class List< ...@@ -2043,10 +2081,13 @@ class List<
return -1; return -1;
}; };
/**
* @see the comment of `List['getId']`.
*/
getId = function (list: List, rawIndex: number): string { getId = function (list: List, rawIndex: number): string {
let id = list._idList[rawIndex]; let id = list._idList[rawIndex];
if (id == null) { if (id == null) {
id = getRawValueFromStore(list, list._idDimIdx, rawIndex); id = convertOptionIdName(getRawValueFromStore(list, list._idDimIdx, rawIndex), null);
} }
if (id == null) { if (id == null) {
// FIXME Check the usage in graph, should not use prefix. // FIXME Check the usage in graph, should not use prefix.
......
...@@ -26,8 +26,12 @@ import Model from '../model/Model'; ...@@ -26,8 +26,12 @@ import Model from '../model/Model';
import linkList from './helper/linkList'; import linkList from './helper/linkList';
import List from './List'; import List from './List';
import createDimensions from './helper/createDimensions'; import createDimensions from './helper/createDimensions';
import { DimensionLoose, ParsedValue } from '../util/types'; import {
DimensionLoose, ParsedValue, OptionId, OptionDataValue,
OptionDataItemObject
} from '../util/types';
import { Dictionary } from 'zrender/src/core/types'; import { Dictionary } from 'zrender/src/core/types';
import { convertOptionIdName } from '../util/model';
type TreeTraverseOrder = 'preorder' | 'postorder'; type TreeTraverseOrder = 'preorder' | 'postorder';
type TreeTraverseCallback<Ctx> = (this: Ctx, node: TreeNode) => boolean | void; type TreeTraverseCallback<Ctx> = (this: Ctx, node: TreeNode) => boolean | void;
...@@ -36,10 +40,8 @@ type TreeTraverseOption = { ...@@ -36,10 +40,8 @@ type TreeTraverseOption = {
attr?: 'children' | 'viewChildren' attr?: 'children' | 'viewChildren'
}; };
interface TreeNodeData { interface TreeNodeOption extends Pick<OptionDataItemObject<OptionDataValue>, 'name' | 'value'> {
name?: string children?: TreeNodeOption[];
value?: any
children?: TreeNodeData[]
} }
export class TreeNode { export class TreeNode {
...@@ -405,7 +407,7 @@ class Tree<HostModel extends Model = Model, LevelOption = any, LeavesOption = an ...@@ -405,7 +407,7 @@ class Tree<HostModel extends Model = Model, LevelOption = any, LeavesOption = an
* ] * ]
* } * }
*/ */
static createTree<T extends TreeNodeData, HostModel extends Model, LevelOption>( static createTree<T extends TreeNodeOption, HostModel extends Model, LevelOption>(
dataRoot: T, dataRoot: T,
hostModel: HostModel, hostModel: HostModel,
treeOptions?: { treeOptions?: {
...@@ -415,18 +417,18 @@ class Tree<HostModel extends Model = Model, LevelOption = any, LeavesOption = an ...@@ -415,18 +417,18 @@ class Tree<HostModel extends Model = Model, LevelOption = any, LeavesOption = an
) { ) {
const tree = new Tree(hostModel, treeOptions && treeOptions.levels); const tree = new Tree(hostModel, treeOptions && treeOptions.levels);
const listData: TreeNodeData[] = []; const listData: TreeNodeOption[] = [];
let dimMax = 1; let dimMax = 1;
buildHierarchy(dataRoot); buildHierarchy(dataRoot);
function buildHierarchy(dataNode: TreeNodeData, parentNode?: TreeNode) { function buildHierarchy(dataNode: TreeNodeOption, parentNode?: TreeNode) {
const value = dataNode.value; const value = dataNode.value;
dimMax = Math.max(dimMax, zrUtil.isArray(value) ? value.length : 1); dimMax = Math.max(dimMax, zrUtil.isArray(value) ? value.length : 1);
listData.push(dataNode); listData.push(dataNode);
const node = new TreeNode(dataNode.name, tree); const node = new TreeNode(convertOptionIdName(dataNode.name, ''), tree);
parentNode parentNode
? addChild(node, parentNode) ? addChild(node, parentNode)
: (tree.root = node); : (tree.root = node);
......
...@@ -20,16 +20,9 @@ ...@@ -20,16 +20,9 @@
import {each, isString} from 'zrender/src/core/util'; import {each, isString} from 'zrender/src/core/util';
import DataDimensionInfo from '../DataDimensionInfo'; import DataDimensionInfo from '../DataDimensionInfo';
import SeriesModel from '../../model/Series'; import SeriesModel from '../../model/Series';
import List from '../List'; import List, { DataCalculationInfo } from '../List';
import type { SeriesOption, SeriesStackOptionMixin, DimensionName } from '../../util/types'; import type { SeriesOption, SeriesStackOptionMixin, DimensionName } from '../../util/types';
interface DataStackResult {
stackedDimension: string
stackedByDimension: string
isStackedByIndex: boolean
stackedOverDimension: string
stackResultDimension: string
}
/** /**
* Note that it is too complicated to support 3d stack by value * Note that it is too complicated to support 3d stack by value
...@@ -58,7 +51,14 @@ export function enableDataStack( ...@@ -58,7 +51,14 @@ export function enableDataStack(
stackedCoordDimension?: string stackedCoordDimension?: string
byIndex?: boolean byIndex?: boolean
} }
): DataStackResult { ): Pick<
DataCalculationInfo<unknown>,
'stackedDimension'
| 'stackedByDimension'
| 'isStackedByIndex'
| 'stackedOverDimension'
| 'stackResultDimension'
> {
opt = opt || {}; opt = opt || {};
let byIndex = opt.byIndex; let byIndex = opt.byIndex;
const stackedCoordDimension = opt.stackedCoordDimension; const stackedCoordDimension = opt.stackedCoordDimension;
......
...@@ -41,7 +41,9 @@ import { ...@@ -41,7 +41,9 @@ import {
OptionDataItem, OptionDataItem,
OptionDataValue, OptionDataValue,
TooltipRenderMode, TooltipRenderMode,
Payload Payload,
OptionId,
OptionName
} from './types'; } from './types';
import { Dictionary } from 'zrender/src/core/types'; import { Dictionary } from 'zrender/src/core/types';
import SeriesModel from '../model/Series'; import SeriesModel from '../model/Series';
...@@ -150,7 +152,7 @@ export function isDataItemOption(dataItem: OptionDataItem): boolean { ...@@ -150,7 +152,7 @@ export function isDataItemOption(dataItem: OptionDataItem): boolean {
// number id will not be converted to string in option. // number id will not be converted to string in option.
// number id will be converted to string in component instance id. // number id will be converted to string in component instance id.
export interface MappingExistingItem { export interface MappingExistingItem {
id?: string | number; id?: OptionId;
name?: string; name?: string;
}; };
/** /**
...@@ -499,7 +501,11 @@ function makeIdAndName( ...@@ -499,7 +501,11 @@ function makeIdAndName(
}); });
} }
function keyExistAndEqual(attr: 'id' | 'name', obj1: MappingExistingItem, obj2: MappingExistingItem): boolean { function keyExistAndEqual(
attr: 'id' | 'name',
obj1: { id?: OptionId, name?: OptionName },
obj2: { id?: OptionId, name?: OptionName }
): boolean {
const key1 = obj1[attr]; const key1 = obj1[attr];
const key2 = obj2[attr]; const key2 = obj2[attr];
// See `MappingExistingItem`. `id` and `name` trade string equals to number. // See `MappingExistingItem`. `id` and `name` trade string equals to number.
...@@ -509,13 +515,22 @@ function keyExistAndEqual(attr: 'id' | 'name', obj1: MappingExistingItem, obj2: ...@@ -509,13 +515,22 @@ function keyExistAndEqual(attr: 'id' | 'name', obj1: MappingExistingItem, obj2:
/** /**
* @return return null if not exist. * @return return null if not exist.
*/ */
function makeComparableKey(val: string | number): string { function makeComparableKey(val: unknown): string {
if (__DEV__) { if (__DEV__) {
if (val == null) { if (val == null) {
throw new Error(); throw new Error();
} }
} }
return val + ''; return convertOptionIdName(val, '');
}
export function convertOptionIdName(idOrName: unknown, defaultValue: string): string {
const type = typeof idOrName;
return type === 'string'
? idOrName as string
: (type === 'number' || isStringSafe(idOrName))
? idOrName + ''
: defaultValue;
} }
export function validateIdOrName(idOrName: unknown) { export function validateIdOrName(idOrName: unknown) {
...@@ -542,7 +557,7 @@ export function isNameSpecified(componentModel: ComponentModel): boolean { ...@@ -542,7 +557,7 @@ export function isNameSpecified(componentModel: ComponentModel): boolean {
* @param {Object} cmptOption * @param {Object} cmptOption
* @return {boolean} * @return {boolean}
*/ */
export function isComponentIdInternal(cmptOption: MappingExistingItem): boolean { export function isComponentIdInternal(cmptOption: { id?: MappingExistingItem['id'] }): boolean {
return cmptOption return cmptOption
&& cmptOption.id != null && cmptOption.id != null
&& makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0; && makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0;
...@@ -733,8 +748,8 @@ let innerUniqueIndex = getRandomIdBase(); ...@@ -733,8 +748,8 @@ let innerUniqueIndex = getRandomIdBase();
* The priority is: index > id > name, the same with `ecModel.queryComponents`. * The priority is: index > id > name, the same with `ecModel.queryComponents`.
*/ */
export type ModelFinderIndexQuery = number | number[] | 'all' | 'none' | false; export type ModelFinderIndexQuery = number | number[] | 'all' | 'none' | false;
export type ModelFinderIdQuery = number | number[] | string | string[]; export type ModelFinderIdQuery = OptionId | OptionId[];
export type ModelFinderNameQuery = number | number[] | string | string[]; export type ModelFinderNameQuery = OptionId | OptionId[];
export type ModelFinder = string | ModelFinderObject; export type ModelFinder = string | ModelFinderObject;
export type ModelFinderObject = { export type ModelFinderObject = {
seriesIndex?: ModelFinderIndexQuery, seriesId?: ModelFinderIdQuery, seriesName?: ModelFinderNameQuery seriesIndex?: ModelFinderIndexQuery, seriesId?: ModelFinderIdQuery, seriesName?: ModelFinderNameQuery
......
...@@ -517,11 +517,15 @@ export type OptionDataItem = ...@@ -517,11 +517,15 @@ export type OptionDataItem =
| OptionDataItemObject<OptionDataValue>; | OptionDataItemObject<OptionDataValue>;
// Only for `SOURCE_FORMAT_KEYED_ORIGINAL` // Only for `SOURCE_FORMAT_KEYED_ORIGINAL`
export type OptionDataItemObject<T> = { export type OptionDataItemObject<T> = {
id?: string | number; id?: OptionId;
name?: string; name?: OptionName;
value?: T[] | T; value?: T[] | T;
selected?: boolean; selected?: boolean;
}; };
// Compat number because it is usually used and not easy to
// restrict it in practise.
export type OptionId = string | number;
export type OptionName = string | number;
export interface GraphEdgeItemObject< export interface GraphEdgeItemObject<
VAL extends OptionDataValue VAL extends OptionDataValue
> extends OptionDataItemObject<VAL> { > extends OptionDataItemObject<VAL> {
...@@ -1247,8 +1251,8 @@ export interface CommonAxisPointerOption { ...@@ -1247,8 +1251,8 @@ export interface CommonAxisPointerOption {
export interface ComponentOption { export interface ComponentOption {
type?: string; type?: string;
id?: string; id?: OptionId;
name?: string; name?: OptionName;
z?: number; z?: number;
zlevel?: number; zlevel?: number;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册