diff --git a/src/api/iseries-primitive-api.ts b/src/api/iseries-primitive-api.ts index 9f1d8a04d6..98e664f2d2 100644 --- a/src/api/iseries-primitive-api.ts +++ b/src/api/iseries-primitive-api.ts @@ -1,3 +1,4 @@ +import { Time } from '../model/horz-scale-behavior-time/types'; import { ISeriesPrimitiveBase } from '../model/iseries-primitive'; import { SeriesOptionsMap, SeriesType } from '../model/series-options'; @@ -9,7 +10,7 @@ import { ISeriesApi } from './iseries-api'; * a refresh of the chart. */ export interface SeriesAttachedParameter< - HorzScaleItem, + HorzScaleItem = Time, TSeriesType extends SeriesType = keyof SeriesOptionsMap > { /** @@ -29,6 +30,6 @@ export interface SeriesAttachedParameter< /** * Interface for series primitives. It must be implemented to add some external graphics to series. */ -export type ISeriesPrimitive = ISeriesPrimitiveBase< +export type ISeriesPrimitive = ISeriesPrimitiveBase< SeriesAttachedParameter >; diff --git a/src/api/series-api.ts b/src/api/series-api.ts index 077e2b6e58..e0a2a8dd34 100644 --- a/src/api/series-api.ts +++ b/src/api/series-api.ts @@ -135,8 +135,6 @@ export class SeriesApi< // actually they can't exist separately if (dataFirstBarInRange !== null && dataLastBarInRange !== null) { - // result.from = dataFirstBarInRange.time.businessDay || dataFirstBarInRange.time.timestamp; - // result.to = dataLastBarInRange.time.businessDay || dataLastBarInRange.time.timestamp; result.from = dataFirstBarInRange.originalTime as HorzScaleItem; result.to = dataLastBarInRange.originalTime as HorzScaleItem; } diff --git a/src/model/horz-scale-behavior-time/time-based-chart-options.ts b/src/model/horz-scale-behavior-time/time-based-chart-options.ts index a2fe524d8a..58fc71cac8 100644 --- a/src/model/horz-scale-behavior-time/time-based-chart-options.ts +++ b/src/model/horz-scale-behavior-time/time-based-chart-options.ts @@ -4,7 +4,7 @@ import { TickMarkFormatter } from './horz-scale-behavior-time'; import { Time } from './types'; /** - * Extended time scale options for time-base horz scale + * Extended time scale options for time-based horizontal scale */ export interface TimeScaleOptions extends HorzScaleOptions { /** diff --git a/src/model/time-scale.ts b/src/model/time-scale.ts index 2ace53d23e..9a0be726e5 100644 --- a/src/model/time-scale.ts +++ b/src/model/time-scale.ts @@ -7,7 +7,6 @@ import { DeepPartial, isInteger, merge } from '../helpers/strict-type-checks'; import { ChartModel } from './chart-model'; import { Coordinate } from './coordinate'; -// import { defaultTickMarkFormatter } from './default-tick-mark-formatter'; import { FormattedLabelsCache } from './formatted-labels-cache'; import { IHorzScaleBehavior, InternalHorzScaleItem, InternalHorzScaleItemKey } from './ihorz-scale-behavior'; import { LocalizationOptions } from './localization-options'; diff --git a/tests/type-checks/non-time-based-custom-series.ts b/tests/type-checks/non-time-based-custom-series.ts new file mode 100644 index 0000000000..0453b9d212 --- /dev/null +++ b/tests/type-checks/non-time-based-custom-series.ts @@ -0,0 +1,108 @@ +import { createChartEx, customSeriesDefaultOptions } from '../../src'; +import { CandlestickData, WhitespaceData } from '../../src/model/data-consumer'; +import { Time } from '../../src/model/horz-scale-behavior-time/types'; +import { CustomData, CustomSeriesPricePlotValues, ICustomSeriesPaneRenderer, ICustomSeriesPaneView, PaneRendererCustomData } from '../../src/model/icustom-series'; +import { IHorzScaleBehavior } from '../../src/model/ihorz-scale-behavior'; +import { CustomSeriesOptions } from '../../src/model/series-options'; + +type HorizontalScaleType = number; + +interface NonTimeSeriesOptions extends CustomSeriesOptions { + testOption: string; +} + +const defaultOptions: NonTimeSeriesOptions = { + ...customSeriesDefaultOptions, + testOption: 'hello', +} as const; + +interface NonTimeData extends CustomData { + priceY: number; +} + +class NonTimeSeries implements ICustomSeriesPaneView { + public priceValueBuilder(plotRow: NonTimeData): CustomSeriesPricePlotValues { + return []; + } + + public isWhitespace(data: NonTimeData | WhitespaceData): data is WhitespaceData { + return (data as Partial).priceY === undefined; + } + + public renderer(): ICustomSeriesPaneRenderer { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + return {} as ICustomSeriesPaneRenderer; + } + + public update( + data: PaneRendererCustomData, + options: NonTimeSeriesOptions + ): void {} + + public defaultOptions(): NonTimeSeriesOptions { + return defaultOptions; + } +} + +// @ts-expect-error Mock Class +class MyHorizontalScaleBehaviour implements IHorzScaleBehavior { + public isMock(): boolean { + return true; + } +} +const horizontalScaleBehaviourMock = new MyHorizontalScaleBehaviour(); + +// @ts-expect-error Mock Class +const chart = createChartEx('anything', horizontalScaleBehaviourMock); +const customSeriesView = (new NonTimeSeries()) as ICustomSeriesPaneView; + +// @ts-expect-error invalid property +const failSeries = chart.addCustomSeries(customSeriesView, { badOption: 123 }); +// @ts-expect-error invalid value +const failSeries2 = chart.addCustomSeries(customSeriesView, { testOption: 123 }); + +const series = chart.addCustomSeries(customSeriesView, { testOption: 'string' }); + +const data: (NonTimeData | WhitespaceData)[] = [ + { time: 12345 }, // whitespace + // @ts-expect-error invalid data + { time: 12345, value: 1234 }, + { time: 12345, priceY: 12345 }, +]; + +series.setData(data); + +series.update({ time: 12345 }); +// @ts-expect-error invalid data +series.update({ time: 12345, value: 1234 }); +series.update({ time: 12345, priceY: 12345 }); + +const notGreatData: CandlestickData[] = [{ time: 12345 as Time, open: 1234, high: 1234, low: 1234, close: 1234 }]; +// @ts-expect-error time is not compatible anymore, type Time isn't always a number +series.setData(notGreatData); + +const badData = [{ open: 1234, high: 1234, low: 1234, close: 1234 }] as const; +// @ts-expect-error data should have at least `time` property +series.setData(badData); + +const options: Readonly = series.options(); +// @ts-expect-error not a valid option +options.baseLineColor = 'orange'; + +// @ts-expect-error invalid property +series.applyOptions({ badOption: 123 }); +// @ts-expect-error invalid value +series.applyOptions({ testOption: 123 }); +series.applyOptions({ testOption: 'string' }); + +type ExpectedDataType = NonTimeData | WhitespaceData; +export const dataPoint: ExpectedDataType | null = series.dataByIndex(1); + +const dataSet: readonly ExpectedDataType[] = series.data(); +if (dataSet) { + // @ts-expect-error readonly array + dataSet[0] = { time: 12 }; +} +// @ts-expect-error readonly array +// eslint-disable-next-line @typescript-eslint/no-unsafe-call +dataSet.push({ time: 12 });