From 2bba2823bde178785ac4865e42af62e21a65e4d9 Mon Sep 17 00:00:00 2001 From: maryia-deriv Date: Mon, 17 Jul 2023 15:20:02 +0300 Subject: [PATCH 1/5] chore: start ts migration --- .../Trading/Helpers/{contract-type.js => contract-type.ts} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename packages/trader/src/Stores/Modules/Trading/Helpers/{contract-type.js => contract-type.ts} (98%) diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.js b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts similarity index 98% rename from packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.js rename to packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts index 81638cd7e01c..6751b19ba4a9 100644 --- a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.js +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts @@ -19,17 +19,18 @@ import { import ServerTime from '_common/base/server_time'; import { localize } from '@deriv/translations'; import { isSessionAvailable } from './start-date'; +import { ContractsForSymbolResponse } from '@deriv/api-types'; export const ContractType = (() => { let available_contract_types = {}; let available_categories = {}; - let contract_types; + let contract_types: ReturnType; const trading_events = {}; const trading_times = {}; let has_only_forward_starting_contracts = false; - const buildContractTypesConfig = symbol => - WS.storage.contractsFor(symbol).then(r => { + const buildContractTypesConfig = (symbol: string) => + WS.storage.contractsFor(symbol).then((r: Required) => { const has_contracts = getPropertyValue(r, ['contracts_for']); has_only_forward_starting_contracts = has_contracts && !r.contracts_for.available.find(contract => contract.start_type !== 'forward'); From 0fd6aae00f52c583b4952806c7eee401cf0b6e46 Mon Sep 17 00:00:00 2001 From: maryia-deriv Date: Tue, 18 Jul 2023 18:52:30 +0300 Subject: [PATCH 2/5] chore: continue ts migration of contract-types --- .../shared/src/utils/helpers/start-date.ts | 16 +++--- .../Modules/Trading/Helpers/contract-type.ts | 52 +++++++++++++------ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/packages/shared/src/utils/helpers/start-date.ts b/packages/shared/src/utils/helpers/start-date.ts index 250d4337b988..695fbcc1c7f7 100644 --- a/packages/shared/src/utils/helpers/start-date.ts +++ b/packages/shared/src/utils/helpers/start-date.ts @@ -1,5 +1,6 @@ import moment from 'moment'; import { toMoment } from '../date'; +import { ContractsFor } from '@deriv/api-types'; type TForwardStartingDates = { blackouts?: unknown[]; @@ -8,10 +9,6 @@ type TForwardStartingDates = { open?: string; }; -type TContract = { - forward_starting_options: TForwardStartingDates[]; -}; - type TConfig = { text: string; value: number; @@ -21,19 +18,22 @@ type TConfig = { }[]; }[]; -export const buildForwardStartingConfig = (contract: TContract, forward_starting_dates: TForwardStartingDates[]) => { +export const buildForwardStartingConfig = ( + contract: ContractsFor['available'][number], + forward_starting_dates?: TForwardStartingDates[] | TConfig +) => { const forward_starting_config: TConfig = []; if ((contract.forward_starting_options || []).length) { - contract.forward_starting_options.forEach(option => { - const duplicated_option = forward_starting_config.find(opt => opt.value === parseInt(option.date)); + (contract.forward_starting_options ?? []).forEach(option => { + const duplicated_option = forward_starting_config.find(opt => opt.value === parseInt(option.date ?? '')); const current_session = { open: toMoment(option.open), close: toMoment(option.close) }; if (duplicated_option) { duplicated_option.sessions.push(current_session); } else { forward_starting_config.push({ text: toMoment(option.date).format('ddd - DD MMM, YYYY'), - value: parseInt(option.date), + value: parseInt(option.date ?? ''), sessions: [current_session], }); } diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts index 6751b19ba4a9..a2e9eee7d911 100644 --- a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts @@ -19,11 +19,28 @@ import { import ServerTime from '_common/base/server_time'; import { localize } from '@deriv/translations'; import { isSessionAvailable } from './start-date'; -import { ContractsForSymbolResponse } from '@deriv/api-types'; +import { ContractsFor, ContractsForSymbolResponse } from '@deriv/api-types'; +import { TTradeStore } from '../../../../Types/common-prop.type'; + +type TConfig = ReturnType[string]['config'] & { + has_spot?: boolean; + durations?: ReturnType; + trade_types?: { [key: string]: string }; + barriers?: ReturnType; + forward_starting_dates?: ReturnType; + growth_rate_range?: unknown[]; + multiplier_range?: unknown[]; + cancellation_range?: unknown[]; +}; + +type TTextValueStrings = { + text: string; + value: string; +}; export const ContractType = (() => { - let available_contract_types = {}; - let available_categories = {}; + let available_contract_types: ReturnType = {}; + let available_categories: ReturnType | Record = {}; let contract_types: ReturnType; const trading_events = {}; const trading_times = {}; @@ -44,32 +61,32 @@ export const ContractType = (() => { key => contract_types[key].trade_types.indexOf(contract.contract_type) !== -1 && (typeof contract_types[key].barrier_count === 'undefined' || - +contract_types[key].barrier_count === contract.barriers) // To distinguish betweeen Rise/Fall & Higher/Lower + Number(contract_types[key].barrier_count) === contract.barriers) // To distinguish betweeen Rise/Fall & Higher/Lower ); if (!type) return; // ignore unsupported contract types if (!available_contract_types[type]) { // extend contract_categories to include what is needed to create the contract list - const sub_cats = + const sub_cats: Array = available_categories[ Object.keys(available_categories).find( key => available_categories[key].categories.indexOf(type) !== -1 - ) + ) ?? '' ].categories; if (!sub_cats) return; - sub_cats[sub_cats.indexOf(type)] = { value: type, text: contract_types[type].title }; + sub_cats[(sub_cats as string[]).indexOf(type)] = { value: type, text: contract_types[type].title }; // populate available contract types available_contract_types[type] = cloneObject(contract_types[type]); } - const config = available_contract_types[type].config || {}; + const config: TConfig = available_contract_types[type].config || {}; // set config values config.has_spot = config.has_spot || contract.start_type === 'spot'; - config.durations = !config.hide_duration && buildDurationConfig(contract, config.durations); + config.durations = config.hide_duration ? undefined : buildDurationConfig(contract, config.durations); config.trade_types = buildTradeTypesConfig(contract, config.trade_types); config.barriers = buildBarriersConfig(contract, config.barriers); config.forward_starting_dates = buildForwardStartingConfig(contract, config.forward_starting_dates); @@ -82,24 +99,27 @@ export const ContractType = (() => { // cleanup categories Object.keys(available_categories).forEach(key => { - available_categories[key].categories = available_categories[key].categories?.filter( - item => typeof item === 'object' - ); + available_categories[key].categories = ( + available_categories[key].categories as Array + )?.filter(item => typeof item === 'object'); if (available_categories[key].categories?.length === 0) { delete available_categories[key]; } }); }); - const buildTradeTypesConfig = (contract, trade_types = {}) => { - trade_types[contract.contract_type] = contract.contract_display; + const buildTradeTypesConfig = ( + contract: ContractsFor['available'][number], + trade_types: { [key: string]: string } = {} + ) => { + trade_types[contract.contract_type] = contract.contract_display ?? ''; return trade_types; }; - const getArrayDefaultValue = (arr_new_values, value) => + const getArrayDefaultValue = (arr_new_values: string[], value: string) => arr_new_values.indexOf(value) !== -1 ? value : arr_new_values[0]; - const getContractValues = store => { + const getContractValues = (store: TTradeStore) => { const { contract_expiry_type, contract_type, From 4a478a605c1195edf2ebc577d9b005e7b6652719 Mon Sep 17 00:00:00 2001 From: maryia-deriv Date: Wed, 19 Jul 2023 18:43:23 +0300 Subject: [PATCH 3/5] chore: add more types to contract-types --- .../src/utils/helpers/__tests__/start-date.ts | 6 +- .../shared/src/utils/helpers/start-date.ts | 9 +- .../Modules/Trading/Helpers/contract-type.ts | 260 +++++++++++------- .../trader/src/Stores/useTraderStores.tsx | 4 + 4 files changed, 172 insertions(+), 107 deletions(-) diff --git a/packages/shared/src/utils/helpers/__tests__/start-date.ts b/packages/shared/src/utils/helpers/__tests__/start-date.ts index 504c4b36eb34..30c20b80ab0c 100644 --- a/packages/shared/src/utils/helpers/__tests__/start-date.ts +++ b/packages/shared/src/utils/helpers/__tests__/start-date.ts @@ -1,9 +1,10 @@ +import { ContractsFor } from '@deriv/api-types'; import { buildForwardStartingConfig } from '../start-date'; describe('start_date', () => { describe('buildForwardStartingConfig', () => { it('Returns empty object when forward_starting_options and forward_starting_dates are both empties', () => { - const contract = { + const contract: ContractsFor['available'][number] = { barrier_category: 'euro_atm', barriers: 0, contract_category: 'callput', @@ -19,7 +20,8 @@ describe('start_date', () => { start_type: 'spot', submarket: 'major_pairs', underlying_symbol: 'frxAUDJPY', - forward_starting_options: [], + forward_starting_options: + [] as unknown as ContractsFor['available'][number]['forward_starting_options'], }; /* eslint-disable no-unused-expressions */ expect(buildForwardStartingConfig(contract, [])).toHaveLength(0); diff --git a/packages/shared/src/utils/helpers/start-date.ts b/packages/shared/src/utils/helpers/start-date.ts index 695fbcc1c7f7..a96a694f4290 100644 --- a/packages/shared/src/utils/helpers/start-date.ts +++ b/packages/shared/src/utils/helpers/start-date.ts @@ -2,13 +2,6 @@ import moment from 'moment'; import { toMoment } from '../date'; import { ContractsFor } from '@deriv/api-types'; -type TForwardStartingDates = { - blackouts?: unknown[]; - close?: string; - date: string; - open?: string; -}; - type TConfig = { text: string; value: number; @@ -20,7 +13,7 @@ type TConfig = { export const buildForwardStartingConfig = ( contract: ContractsFor['available'][number], - forward_starting_dates?: TForwardStartingDates[] | TConfig + forward_starting_dates?: TConfig ) => { const forward_starting_config: TConfig = []; diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts index a2e9eee7d911..a3c107496d1d 100644 --- a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts @@ -19,34 +19,60 @@ import { import ServerTime from '_common/base/server_time'; import { localize } from '@deriv/translations'; import { isSessionAvailable } from './start-date'; -import { ContractsFor, ContractsForSymbolResponse } from '@deriv/api-types'; +import { ContractsFor, ContractsForSymbolResponse, TradingTimes, TradingTimesResponse } from '@deriv/api-types'; import { TTradeStore } from '../../../../Types/common-prop.type'; +type TAvailableCategories = { + [key: string]: { + name: string; + categories: Array; + }; +}; +type TBarriers = Record< + keyof TTradeStore['duration_min_max'], + { + barrier?: string; + high_barrier?: string; + low_barrier?: string; + } +> & { + count: number; +}; type TConfig = ReturnType[string]['config'] & { has_spot?: boolean; durations?: ReturnType; trade_types?: { [key: string]: string }; barriers?: ReturnType; forward_starting_dates?: ReturnType; - growth_rate_range?: unknown[]; - multiplier_range?: unknown[]; - cancellation_range?: unknown[]; + growth_rate_range?: number[]; + multiplier_range?: number[]; + cancellation_range?: string[]; }; type TTextValueStrings = { text: string; value: string; }; +type TTimes = { + open: string[]; + close: string[]; +}; +type TEvents = + | { + dates: string; + descrip: string; + }[] + | []; export const ContractType = (() => { let available_contract_types: ReturnType = {}; - let available_categories: ReturnType | Record = {}; + let available_categories: TAvailableCategories = {}; let contract_types: ReturnType; - const trading_events = {}; - const trading_times = {}; + const trading_events: { [key: string]: Record } = {}; + const trading_times: { [key: string]: Record } = {}; let has_only_forward_starting_contracts = false; - const buildContractTypesConfig = (symbol: string) => + const buildContractTypesConfig = (symbol: string): Promise => WS.storage.contractsFor(symbol).then((r: Required) => { const has_contracts = getPropertyValue(r, ['contracts_for']); has_only_forward_starting_contracts = @@ -68,7 +94,7 @@ export const ContractType = (() => { if (!available_contract_types[type]) { // extend contract_categories to include what is needed to create the contract list - const sub_cats: Array = + const sub_cats = available_categories[ Object.keys(available_categories).find( key => available_categories[key].categories.indexOf(type) !== -1 @@ -90,18 +116,18 @@ export const ContractType = (() => { config.trade_types = buildTradeTypesConfig(contract, config.trade_types); config.barriers = buildBarriersConfig(contract, config.barriers); config.forward_starting_dates = buildForwardStartingConfig(contract, config.forward_starting_dates); - config.growth_rate_range = contract.growth_rate_range; - config.multiplier_range = contract.multiplier_range; - config.cancellation_range = contract.cancellation_range; + config.growth_rate_range = contract.growth_rate_range as TConfig['growth_rate_range']; + config.multiplier_range = contract.multiplier_range as TConfig['multiplier_range']; + config.cancellation_range = contract.cancellation_range as TConfig['cancellation_range']; available_contract_types[type].config = config; }); // cleanup categories Object.keys(available_categories).forEach(key => { - available_categories[key].categories = ( - available_categories[key].categories as Array - )?.filter(item => typeof item === 'object'); + available_categories[key].categories = available_categories[key].categories?.filter( + item => typeof item === 'object' + ); if (available_categories[key].categories?.length === 0) { delete available_categories[key]; } @@ -116,7 +142,7 @@ export const ContractType = (() => { return trade_types; }; - const getArrayDefaultValue = (arr_new_values: string[], value: string) => + const getArrayDefaultValue = (arr_new_values: Array, value: string | number) => arr_new_values.indexOf(value) !== -1 ? value : arr_new_values[0]; const getContractValues = (store: TTradeStore) => { @@ -148,7 +174,7 @@ export const ContractType = (() => { const obj_accumulator_range_list = getAccumulatorRange(contract_type); const obj_multiplier_range_list = getMultiplierRange(contract_type, multiplier); const obj_cancellation = getCancellation(contract_type, cancellation_duration, symbol); - const obj_expiry_type = getExpiryType(obj_duration_units_list, expiry_type); + const obj_expiry_type = getExpiryType(obj_duration_units_list.duration_units_list, expiry_type); const obj_equal = getEqualProps(contract_type); return { @@ -169,9 +195,12 @@ export const ContractType = (() => { }; }; - const getContractType = (list, contract_type) => { - const arr_list = Object.keys(list || {}) - .reduce((k, l) => [...k, ...list[l].categories.map(ct => ct.value)], []) + const getContractType = (list: TAvailableCategories, contract_type: string) => { + const arr_list: string[] = Object.keys(list || {}) + .reduce( + (k, l) => [...k, ...(list[l].categories as TTextValueStrings[]).map(ct => ct.value)], + [] as string[] + ) .filter(type => unsupported_contract_types_list.indexOf(type) === -1) .sort((a, b) => (a === 'multiplier' || b === 'multiplier' ? -1 : 0)); @@ -180,7 +209,7 @@ export const ContractType = (() => { }; }; - const getComponents = c_type => { + const getComponents = (c_type: string) => { let check = []; if (contract_types[c_type]?.config?.should_override) { check = [...contract_types[c_type].components]; @@ -190,7 +219,7 @@ export const ContractType = (() => { !( component === 'duration' && contract_types[c_type].config && - contract_types[c_type].config.hide_duration + (contract_types[c_type].config as TConfig).hide_duration ) ); } @@ -201,29 +230,29 @@ export const ContractType = (() => { ); }; - const getDurationUnitsList = (contract_type, contract_start_type) => { + const getDurationUnitsList = (contract_type: string, contract_start_type: string) => { return { duration_units_list: - getPropertyValue(available_contract_types, [ + (getPropertyValue(available_contract_types, [ contract_type, 'config', 'durations', 'units_display', contract_start_type, - ]) || [], + ]) as TTextValueStrings[]) || [], }; }; - const getDurationUnit = (duration_unit, contract_type, contract_start_type) => { + const getDurationUnit = (duration_unit: string, contract_type: string, contract_start_type: string) => { const duration_units = - getPropertyValue(available_contract_types, [ + (getPropertyValue(available_contract_types, [ contract_type, 'config', 'durations', 'units_display', contract_start_type, - ]) || []; - const arr_units = []; + ]) as TTextValueStrings[]) || []; + const arr_units: string[] = []; duration_units.forEach(obj => { arr_units.push(obj.value); }); @@ -233,8 +262,8 @@ export const ContractType = (() => { }; }; - const getDurationMinMax = (contract_type, contract_start_type, contract_expiry_type) => { - let duration_min_max = + const getDurationMinMax = (contract_type: string, contract_start_type: string, contract_expiry_type?: string) => { + let duration_min_max: TTradeStore['duration_min_max'] | TTradeStore['duration_min_max'][string] = getPropertyValue(available_contract_types, [ contract_type, 'config', @@ -244,7 +273,7 @@ export const ContractType = (() => { ]) || {}; if (contract_expiry_type) { - duration_min_max = duration_min_max[contract_expiry_type] || {}; + duration_min_max = (duration_min_max as TTradeStore['duration_min_max'])[contract_expiry_type] || {}; } return { duration_min_max }; @@ -252,13 +281,13 @@ export const ContractType = (() => { const getFullContractTypes = () => available_contract_types; - const getStartType = start_date => ({ + const getStartType = (start_date: number) => ({ // Number(0) refers to 'now' contract_start_type: start_date === Number(0) ? 'spot' : 'forward', }); - const getStartDates = (contract_type, current_start_date) => { - const config = getPropertyValue(available_contract_types, [contract_type, 'config']); + const getStartDates = (contract_type: string, current_start_date: number) => { + const config: TConfig = getPropertyValue(available_contract_types, [contract_type, 'config']); const start_dates_list = []; if (config?.has_spot) { @@ -276,8 +305,8 @@ export const ContractType = (() => { return { start_date, start_dates_list }; }; - const getSessions = (contract_type, start_date) => { - const config = getPropertyValue(available_contract_types, [contract_type, 'config']) || {}; + const getSessions = (contract_type: string, start_date: number) => { + const config: TConfig = getPropertyValue(available_contract_types, [contract_type, 'config']) || {}; const sessions = ((config.forward_starting_dates || []).find(option => option.value === start_date) || {}) .sessions; return { sessions }; @@ -286,60 +315,76 @@ export const ContractType = (() => { const hours = [...Array(24).keys()].map(a => `0${a}`.slice(-2)); const minutes = [...Array(12).keys()].map(a => `0${a * 5}`.slice(-2)); - const getValidTime = (sessions, compare_moment, start_moment) => { + const getValidTime = ( + sessions: ReturnType['sessions'], + compare_moment: moment.Moment, + start_moment?: moment.Moment + ) => { if (sessions && !isSessionAvailable(sessions, compare_moment)) { // first see if changing the minute brings it to the right session compare_moment.minute( - minutes.find(m => isSessionAvailable(sessions, compare_moment.minute(m))) || compare_moment.format('mm') + Number( + minutes.find(m => isSessionAvailable(sessions, compare_moment.minute(+m))) || + compare_moment.format('mm') + ) ); // if not, also change the hour if (!isSessionAvailable(sessions, compare_moment)) { compare_moment.minute(0); compare_moment.hour( - hours.find(h => isSessionAvailable(sessions, compare_moment.hour(h), start_moment, true)) || - compare_moment.format('HH') + Number( + hours.find(h => isSessionAvailable(sessions, compare_moment.hour(+h), start_moment, true)) || + compare_moment.format('HH') + ) ); compare_moment.minute( - minutes.find(m => isSessionAvailable(sessions, compare_moment.minute(m))) || - compare_moment.format('mm') + Number( + minutes.find(m => isSessionAvailable(sessions, compare_moment.minute(+m))) || + compare_moment.format('mm') + ) ); } } return compare_moment.format('HH:mm'); }; - const buildMoment = (date, time) => { - const [hour, minute] = isTimeValid(time) ? time.split(':') : [0, 0]; + const buildMoment = (date: string | number | null, time?: string | null) => { + const [hour, minute] = isTimeValid(time ?? '') ? time?.split(':') ?? [] : [0, 0]; return toMoment(date || ServerTime.get()) - .hour(hour) - .minute(minute); + .hour(+hour) + .minute(+minute); }; - const getStartTime = (sessions, start_date, start_time) => ({ + const getStartTime = ( + sessions: ReturnType['sessions'], + start_date: number, + start_time: string | null + ) => ({ start_time: start_date ? getValidTime(sessions, buildMoment(start_date, start_time)) : null, }); - const getTradingEvents = async (date, underlying = null) => { + const getTradingEvents = async (date: string, underlying: string | null = null) => { if (!date) { return []; } if (!(date in trading_events)) { - const trading_times_response = await WS.tradingTimes(date); - + const trading_times_response: TradingTimesResponse = await WS.tradingTimes(date); + const trading_times_data = trading_times_response.trading_times as TradingTimes; if (getPropertyValue(trading_times_response, ['trading_times', 'markets'])) { - for (let i = 0; i < trading_times_response.trading_times.markets.length; i++) { - const submarkets = trading_times_response.trading_times.markets[i].submarkets; + for (let i = 0; i < trading_times_data.markets.length; i++) { + const submarkets = trading_times_data.markets[i].submarkets; if (submarkets) { for (let j = 0; j < submarkets.length; j++) { const symbols = submarkets[j].symbols; if (symbols) { for (let k = 0; k < symbols.length; k++) { const symbol = symbols[k]; - if (!trading_events[trading_times_response.echo_req.trading_times]) { - trading_events[trading_times_response.echo_req.trading_times] = {}; + if (!trading_events[trading_times_response.echo_req.trading_times as string]) { + trading_events[trading_times_response.echo_req.trading_times as string] = {}; } - trading_events[trading_times_response.echo_req.trading_times][symbol.symbol] = - symbol.events; + trading_events[trading_times_response.echo_req.trading_times as string][ + symbol.symbol + ] = symbol.events as TEvents; } } } @@ -348,32 +393,37 @@ export const ContractType = (() => { } } - return trading_events[date][underlying]; + return trading_events[date][underlying as string]; }; - const getTradingTimes = async (date, underlying = null) => { + const getTradingTimes = async ( + date: string | null, + underlying: string | null = null + ): Promise<[] | TTimes | Record> => { if (!date) { return []; } if (!(date in trading_times)) { - const trading_times_response = await WS.tradingTimes(date); - + const trading_times_response: TradingTimesResponse = await WS.tradingTimes(date); + const trading_times_data = trading_times_response.trading_times as TradingTimes; if (getPropertyValue(trading_times_response, ['trading_times', 'markets'])) { - for (let i = 0; i < trading_times_response.trading_times.markets.length; i++) { - const submarkets = trading_times_response.trading_times.markets[i].submarkets; + for (let i = 0; i < trading_times_data.markets.length; i++) { + const submarkets = trading_times_data.markets[i].submarkets; if (submarkets) { for (let j = 0; j < submarkets.length; j++) { const symbols = submarkets[j].symbols; if (symbols) { for (let k = 0; k < symbols.length; k++) { const symbol = symbols[k]; - if (!trading_times[trading_times_response.echo_req.trading_times]) { - trading_times[trading_times_response.echo_req.trading_times] = {}; + if (!trading_times[trading_times_response.echo_req.trading_times as string]) { + trading_times[trading_times_response.echo_req.trading_times as string] = {}; } - trading_times[trading_times_response.echo_req.trading_times][symbol.symbol] = { - open: symbol.times.open, - close: symbol.times.close, + trading_times[trading_times_response.echo_req.trading_times as string][ + symbol.symbol + ] = { + open: (symbol.times as TTimes).open, + close: (symbol.times as TTimes).close, }; } } @@ -386,7 +436,10 @@ export const ContractType = (() => { return underlying ? trading_times[date][underlying] : trading_times[date]; }; - const getExpiryType = (duration_units_list, expiry_type) => { + const getExpiryType = ( + duration_units_list: ReturnType['duration_units_list'], + expiry_type: string | null + ) => { if (duration_units_list) { if ( (!expiry_type && duration_units_list.length > 0) || @@ -404,7 +457,12 @@ export const ContractType = (() => { return { expiry_type }; }; - const getExpiryDate = (duration_units_list, expiry_date, expiry_type, start_date) => { + const getExpiryDate = ( + duration_units_list: ReturnType['duration_units_list'], + expiry_date: string | null, + expiry_type: string | null, + start_date: number + ) => { let proper_expiry_date = null; if (expiry_type === 'endtime') { @@ -432,15 +490,15 @@ export const ContractType = (() => { // first check if end time is within available sessions // then confirm that end time is at least 5 minute after start time const getExpiryTime = ( - expiry_date, - expiry_time, - expiry_type, - market_close_times, - sessions, - start_date, - start_time + expiry_date: string | null, + expiry_time: string | null, + expiry_type: string | null, + market_close_times: string[] | undefined, + sessions: TTradeStore['sessions'], + start_date: number, + start_time: string | null ) => { - let end_time = null; + let end_time: moment.Moment | string | null = null; if (expiry_type === 'endtime') { let market_close_time = '23:59:59'; @@ -478,7 +536,7 @@ export const ContractType = (() => { sessions && !isSessionAvailable(sessions, start_moment.clone().add(5, 'minutes')); end_time = start_moment.clone().add(is_end_of_day || is_end_of_session ? 0 : 5, 'minutes'); // Set the end_time to be multiple of 5 to be equal as the SELECTED_TIME that shown to the client. - end_time = setMinuteMultipleByFive(end_time).format('HH:mm'); + end_time = setMinuteMultipleByFive(end_time as moment.Moment).format('HH:mm'); } // Set the expiry_time to 5 minute less than start_time for forwading contracts when the expiry_time is null and the expiry_date is tomorrow. if (end_time === '00:00' && start_moment.isBefore(end_moment, 'day')) { @@ -489,14 +547,16 @@ export const ContractType = (() => { return { expiry_time: end_time }; }; - const setMinuteMultipleByFive = moment_obj => moment_obj.minute(Math.ceil(moment_obj.minute() / 5) * 5); + const setMinuteMultipleByFive = (moment_obj: moment.Moment) => + moment_obj.minute(Math.ceil(moment_obj.minute() / 5) * 5); - const getTradeTypes = contract_type => ({ - trade_types: getPropertyValue(available_contract_types, [contract_type, 'config', 'trade_types']), + const getTradeTypes = (contract_type: string) => ({ + trade_types: getPropertyValue(available_contract_types, [contract_type, 'config', 'trade_types']) as string[], }); - const getBarriers = (contract_type, expiry_type) => { - const barriers = getPropertyValue(available_contract_types, [contract_type, 'config', 'barriers']) || {}; + const getBarriers = (contract_type: string, expiry_type: string) => { + const barriers = + (getPropertyValue(available_contract_types, [contract_type, 'config', 'barriers']) as TBarriers) || {}; const barrier_values = barriers[expiry_type] || {}; const barrier_1 = barrier_values.barrier || barrier_values.high_barrier || ''; const barrier_2 = barrier_values.low_barrier || ''; @@ -507,10 +567,13 @@ export const ContractType = (() => { }; }; - const getBasis = (contract_type, basis) => { - const arr_basis = getPropertyValue(available_contract_types, [contract_type, 'basis']) || []; + const getBasis = (contract_type: string, basis: string) => { + const arr_basis: string[] = getPropertyValue(available_contract_types, [contract_type, 'basis']) || []; const localized_basis = getLocalizedBasis(); - const basis_list = arr_basis.reduce((cur, bas) => [...cur, { text: localized_basis[bas], value: bas }], []); + const basis_list = arr_basis.reduce( + (cur, bas) => [...cur, { text: localized_basis[bas as keyof typeof localized_basis], value: bas }], + [] as TTextValueStrings[] + ); return { basis_list, @@ -518,13 +581,14 @@ export const ContractType = (() => { }; }; - const getAccumulatorRange = contract_type => ({ + const getAccumulatorRange = (contract_type: string) => ({ accumulator_range_list: - getPropertyValue(available_contract_types, [contract_type, 'config', 'growth_rate_range']) || [], + (getPropertyValue(available_contract_types, [contract_type, 'config', 'growth_rate_range']) as number[]) || + [], }); - const getMultiplierRange = (contract_type, multiplier) => { - const arr_multiplier = + const getMultiplierRange = (contract_type: string, multiplier: number) => { + const arr_multiplier: number[] = getPropertyValue(available_contract_types, [contract_type, 'config', 'multiplier_range']) || []; return { @@ -533,15 +597,17 @@ export const ContractType = (() => { }; }; - const getCancellation = (contract_type, cancellation_duration, symbol) => { - const arr_cancellation_range = + const getCancellation = (contract_type: string, cancellation_duration: string, symbol: string) => { + const arr_cancellation_range: string[] = getPropertyValue(available_contract_types, [contract_type, 'config', 'cancellation_range']) || []; const regex = new RegExp('^([0-9]+)|([a-zA-Z]+)$', 'g'); - const getText = str => { - const [duration, unit] = str.match(regex); + const getText = (str: string) => { + const [duration, unit] = str.match(regex) ?? []; const unit_map = getUnitMap(); - return `${duration} ${unit_map[unit].name_plural}`; + const unit_names = unit_map[unit as keyof typeof unit_map]; + const name = 'name_plural' in unit_names ? unit_names.name_plural : unit_names.name; + return `${duration} ${name}`; }; const should_show_cancellation = shouldShowCancellation(symbol); @@ -553,7 +619,7 @@ export const ContractType = (() => { }; }; - const getEqualProps = contract_type => { + const getEqualProps = (contract_type: string) => { const base_contract_type = /^(.*)_equal$/.exec(contract_type)?.[1]; if (base_contract_type && !available_contract_types[base_contract_type]) { diff --git a/packages/trader/src/Stores/useTraderStores.tsx b/packages/trader/src/Stores/useTraderStores.tsx index b8307bf0570d..b72249aaa503 100644 --- a/packages/trader/src/Stores/useTraderStores.tsx +++ b/packages/trader/src/Stores/useTraderStores.tsx @@ -63,10 +63,12 @@ type TOverrideTradeStore = Omit< | 'market_close_times' | 'market_open_times' | 'multiplier_range_list' + | 'multiplier' | 'sessions' | 'setIsTradeParamsExpanded' | 'start_dates_list' | 'start_time' + | 'symbol' | 'take_profit' | 'proposal_info' | 'trade_types' @@ -89,6 +91,7 @@ type TOverrideTradeStore = Omit< form_components: string[]; market_open_times: string[]; market_close_times: string[]; + multiplier: number; multiplier_range_list: number[]; proposal_info: { [key: string]: { @@ -109,6 +112,7 @@ type TOverrideTradeStore = Omit< setIsTradeParamsExpanded: (value: boolean) => void; start_dates_list: Array<{ text: string; value: number }>; start_time: string | null; + symbol: string; take_profit?: string; ticks_history_stats: { ticks_stayed_in?: number[]; From 7dac502eecdfd0b8ddb14de3016f2d0103389dd0 Mon Sep 17 00:00:00 2001 From: maryia-deriv Date: Wed, 19 Jul 2023 18:59:52 +0300 Subject: [PATCH 4/5] chore: add type for getContractValues return value --- .../Modules/Trading/Helpers/contract-type.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts index a3c107496d1d..60506a794306 100644 --- a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts @@ -48,7 +48,6 @@ type TConfig = ReturnType[string]['config'] & { multiplier_range?: number[]; cancellation_range?: string[]; }; - type TTextValueStrings = { text: string; value: string; @@ -65,6 +64,21 @@ type TEvents = | []; export const ContractType = (() => { + type TContractValues = ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType & + ReturnType; + let available_contract_types: ReturnType = {}; let available_categories: TAvailableCategories = {}; let contract_types: ReturnType; @@ -145,7 +159,7 @@ export const ContractType = (() => { const getArrayDefaultValue = (arr_new_values: Array, value: string | number) => arr_new_values.indexOf(value) !== -1 ? value : arr_new_values[0]; - const getContractValues = (store: TTradeStore) => { + const getContractValues = (store: TTradeStore): TContractValues | Record => { const { contract_expiry_type, contract_type, From 168695f343f564a44035602890a8c3c162d7d44f Mon Sep 17 00:00:00 2001 From: maryia-deriv Date: Thu, 20 Jul 2023 12:28:39 +0300 Subject: [PATCH 5/5] chore: improve reduce types --- .../src/Stores/Modules/Trading/Helpers/contract-type.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts index 60506a794306..a6b164b61b23 100644 --- a/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/contract-type.ts @@ -211,10 +211,7 @@ export const ContractType = (() => { const getContractType = (list: TAvailableCategories, contract_type: string) => { const arr_list: string[] = Object.keys(list || {}) - .reduce( - (k, l) => [...k, ...(list[l].categories as TTextValueStrings[]).map(ct => ct.value)], - [] as string[] - ) + .reduce((k, l) => [...k, ...(list[l].categories as TTextValueStrings[]).map(ct => ct.value)], []) .filter(type => unsupported_contract_types_list.indexOf(type) === -1) .sort((a, b) => (a === 'multiplier' || b === 'multiplier' ? -1 : 0)); @@ -584,9 +581,9 @@ export const ContractType = (() => { const getBasis = (contract_type: string, basis: string) => { const arr_basis: string[] = getPropertyValue(available_contract_types, [contract_type, 'basis']) || []; const localized_basis = getLocalizedBasis(); - const basis_list = arr_basis.reduce( + const basis_list = arr_basis.reduce( (cur, bas) => [...cur, { text: localized_basis[bas as keyof typeof localized_basis], value: bas }], - [] as TTextValueStrings[] + [] ); return {