From 53b81e6417597f72fb5cbdad4c0b4da77b89e255 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Tue, 9 Apr 2019 17:00:10 -0500 Subject: [PATCH 1/5] remove keyOfStringsOnly from tsConfig; associated changes --- src/components/badge/index.d.ts | 17 ++++++++++++----- .../notification_badge/badge_notification.tsx | 4 ++-- .../drag_and_drop/drag_drop_context.tsx | 12 ++++++++++-- src/components/flex/flex_grid.tsx | 4 ++-- src/components/icon/icon.tsx | 8 +++++--- src/services/format/format_date.ts | 6 +++++- tsconfig.json | 3 --- 7 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/components/badge/index.d.ts b/src/components/badge/index.d.ts index f966ef9f003..bc8ef6ef073 100644 --- a/src/components/badge/index.d.ts +++ b/src/components/badge/index.d.ts @@ -1,11 +1,15 @@ -import { IconType } from '../icon' +import { IconType } from '../icon'; /// -import { HTMLAttributes, MouseEventHandler, FunctionComponent, ReactNode } from 'react'; -import { CommonProps } from '../common'; +import { + HTMLAttributes, + MouseEventHandler, + FunctionComponent, + ReactNode, +} from 'react'; +import { CommonProps, Omit } from '../common'; declare module '@elastic/eui' { - type IconSide = 'left' | 'right'; export interface EuiBadgeProps { @@ -20,7 +24,10 @@ declare module '@elastic/eui' { } export const EuiBadge: FunctionComponent< - CommonProps & HTMLAttributes & HTMLAttributes & EuiBadgeProps + CommonProps & + Omit, 'color'> & + Omit, 'color'> & + EuiBadgeProps >; export interface EuiBetaBadgeProps { diff --git a/src/components/badge/notification_badge/badge_notification.tsx b/src/components/badge/notification_badge/badge_notification.tsx index 107973a2deb..b05f5851597 100644 --- a/src/components/badge/notification_badge/badge_notification.tsx +++ b/src/components/badge/notification_badge/badge_notification.tsx @@ -1,6 +1,6 @@ import React, { HTMLAttributes, ReactNode, FunctionComponent } from 'react'; import classNames from 'classnames'; -import { CommonProps, keysOf } from '../../common'; +import { CommonProps, Omit, keysOf } from '../../common'; const colorToClassMap: { [color: string]: string | null } = { accent: null, @@ -20,7 +20,7 @@ export type BadgeNotificationSize = keyof typeof sizeToClassNameMap; export interface EuiNotificationBadgeProps extends CommonProps, - HTMLAttributes { + Omit, 'color'> { children: ReactNode; size?: BadgeNotificationSize; color?: BadgeNotificationColor; diff --git a/src/components/drag_and_drop/drag_drop_context.tsx b/src/components/drag_and_drop/drag_drop_context.tsx index b76cb6d87e3..cc469b8dfb4 100644 --- a/src/components/drag_and_drop/drag_drop_context.tsx +++ b/src/components/drag_and_drop/drag_drop_context.tsx @@ -9,7 +9,15 @@ import { // export interface EuiDragDropContextProps extends DragDropContextProps {} -export const EuiDragDropContextContext = React.createContext({ +type EuiDraggingType = string | null; + +interface EuiDraggingContext { + isDraggingType: EuiDraggingType; +} + +export const EuiDragDropContextContext = React.createContext< + EuiDraggingContext +>({ isDraggingType: null, }); @@ -21,7 +29,7 @@ export const EuiDragDropContext: FunctionComponent = ({ children, ...rest }) => { - const [isDraggingType, setIsDraggingType] = useState(); + const [isDraggingType, setIsDraggingType] = useState(null); const euiOnDragStart = ( start: DragStart, provided: ResponderProvided diff --git a/src/components/flex/flex_grid.tsx b/src/components/flex/flex_grid.tsx index d546a73bd89..7a5254c3d87 100644 --- a/src/components/flex/flex_grid.tsx +++ b/src/components/flex/flex_grid.tsx @@ -32,8 +32,8 @@ const columnsToClassNameMap = { 4: 'euiFlexGrid--fourths', }; -export const COLUMNS = keysOf(columnsToClassNameMap).map(columns => - parseInt(columns, 10) +export const COLUMNS = Object.keys(columnsToClassNameMap).map( + (columns: string) => parseInt(columns, 10) ) as FlexGridColumns[]; export const EuiFlexGrid: FunctionComponent< diff --git a/src/components/icon/icon.tsx b/src/components/icon/icon.tsx index 123618071bb..5bf7ab49e39 100644 --- a/src/components/icon/icon.tsx +++ b/src/components/icon/icon.tsx @@ -1,7 +1,7 @@ import React, { FunctionComponent, SVGAttributes } from 'react'; import classNames from 'classnames'; -import { CommonProps, keysOf } from '../common'; +import { CommonProps, Omit, keysOf } from '../common'; import addDataApp from './assets/app_add_data.svg'; import advancedSettingsApp from './assets/app_advanced_settings.svg'; @@ -619,7 +619,7 @@ const colorToClassMap: { [color: string]: string | null } = { export const COLORS: IconColor[] = keysOf(colorToClassMap); // We accept arbitrary color strings, which are impossible to type. -export type IconColor = string | keyof typeof colorToClassMap; +export type IconColor = string | Extract; const sizeToClassNameMap = { original: null, @@ -643,7 +643,9 @@ export interface EuiIconProps { size?: IconSize; } -type Props = CommonProps & SVGAttributes & EuiIconProps; +type Props = CommonProps & + Omit, 'color'> & + EuiIconProps; export const EuiIcon: FunctionComponent = ({ type, diff --git a/src/services/format/format_date.ts b/src/services/format/format_date.ts index e34cbdf8f48..4ae4afc9ec7 100644 --- a/src/services/format/format_date.ts +++ b/src/services/format/format_date.ts @@ -71,7 +71,11 @@ export const formatDate = ( return moment(value).format(dateFormatStr); } - const { format = 'dateTime', nil = '', options } = dateFormatKeyOrConfig; + const { + format = 'dateTime', + nil = '', + options, + } = dateFormatKeyOrConfig as FormatDateConfig; const dateFormat = dateFormatAliases[format] || format; diff --git a/tsconfig.json b/tsconfig.json index 8d973adad6d..5d4835cadaa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -37,9 +37,6 @@ // Disallow inconsistently-cased references to the same file. "forceConsistentCasingInFileNames": true, - // Disable the breaking keyof behaviour introduced in TS 2.9.2 until EUI is updated to support that too - "keyofStringsOnly": true, - // enables "core language features" "lib": [ // ESNext auto includes previous versions all the way back to es5 From f8f622a2083ea072a344e13f001971ba38da9fb5 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Tue, 9 Apr 2019 17:02:20 -0500 Subject: [PATCH 2/5] pass webpack output to console on build --- scripts/compile-eui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/compile-eui.js b/scripts/compile-eui.js index 53bb3322c21..1c9dcf721d6 100755 --- a/scripts/compile-eui.js +++ b/scripts/compile-eui.js @@ -44,10 +44,10 @@ function compileBundle() { shell.mkdir('-p', 'dist'); console.log('Building bundle...'); - execSync('webpack --config=src/webpack.config.js'); + execSync('webpack --config=src/webpack.config.js', { stdio: 'inherit' }); console.log('Building minified bundle...'); - execSync('NODE_ENV=production webpack --config=src/webpack.config.js'); + execSync('NODE_ENV=production webpack --config=src/webpack.config.js', { stdio: 'inherit' }); } compileLib(); From 054894b918d2f569aeae06413aecdb3b3f9a6be8 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 11 Apr 2019 16:11:50 -0500 Subject: [PATCH 3/5] revert Extract in icon.tsx; cast-less update of format_date.ts --- src/components/icon/icon.tsx | 2 +- src/services/format/format_date.ts | 64 ++++++++++++++------- src/services/predicate/common_predicates.ts | 8 +-- src/services/predicate/lodash_predicates.ts | 3 +- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/components/icon/icon.tsx b/src/components/icon/icon.tsx index 5bf7ab49e39..03788e08477 100644 --- a/src/components/icon/icon.tsx +++ b/src/components/icon/icon.tsx @@ -619,7 +619,7 @@ const colorToClassMap: { [color: string]: string | null } = { export const COLORS: IconColor[] = keysOf(colorToClassMap); // We accept arbitrary color strings, which are impossible to type. -export type IconColor = string | Extract; +export type IconColor = string | keyof typeof colorToClassMap; const sizeToClassNameMap = { original: null, diff --git a/src/services/format/format_date.ts b/src/services/format/format_date.ts index 4ae4afc9ec7..7fe977b35b8 100644 --- a/src/services/format/format_date.ts +++ b/src/services/format/format_date.ts @@ -5,12 +5,12 @@ type CalendarOptions = CalendarSpec & { refTime?: MomentInput; }; -const calendar = (value: Date, options: CalendarOptions = {}) => { +const calendar = (value: MomentInput, options: CalendarOptions = {}) => { const refTime = options.refTime; return moment(value).calendar(refTime, options); }; -export const dateFormatAliases: { [alias: string]: any } = { +export const dateFormatAliases = { date: 'D MMM YYYY', longDate: 'DD MMMM YYYY', shortDate: 'D MMM YY', @@ -21,7 +21,7 @@ export const dateFormatAliases: { [alias: string]: any } = { dobLong: 'Do MMMM YYYY', iso8601: 'YYYY-MM-DDTHH:mm:ss.SSSZ', calendar, - calendarDateTime: (value: Date, options: CalendarSpec) => { + calendarDateTime: (value: MomentInput, options: CalendarSpec) => { return calendar(value, { sameDay: '[Today at] H:mmA', nextDay: '[Tomorrow at] H:mmA', @@ -32,7 +32,7 @@ export const dateFormatAliases: { [alias: string]: any } = { ...options, }); }, - calendarDate: (value: Date, options: CalendarSpec) => { + calendarDate: (value: MomentInput, options: CalendarSpec) => { return calendar(value, { sameDay: '[Today]', nextDay: '[Tomorrow]', @@ -53,6 +53,19 @@ interface FormatDateConfig { options: any; } +function isStringADateFormat(x: string): x is DateFormat { + return dateFormatAliases.hasOwnProperty(x); +} + +function instanceOfFormatDateConfig(x: any): x is Partial { + return ( + typeof x === 'object' && + (x.hasOwnProperty('format') || + x.hasOwnProperty('nil') || + x.hasOwnProperty('options')) + ); +} + export const formatDate = ( value?: MomentInput, dateFormatKeyOrConfig: @@ -65,27 +78,38 @@ export const formatDate = ( return ''; } - const dateFormatStr = - dateFormatAliases[dateFormatKeyOrConfig] || dateFormatKeyOrConfig; + const dateFormatStrOrFunc = isStringADateFormat(dateFormatKeyOrConfig) + ? dateFormatAliases[dateFormatKeyOrConfig] + : dateFormatKeyOrConfig; + + if (isString(dateFormatStrOrFunc)) { + return moment(value).format(dateFormatStrOrFunc); + } + + if (isFunction(dateFormatStrOrFunc)) { + return dateFormatStrOrFunc(value, {}); + } - return moment(value).format(dateFormatStr); + if (isString(dateFormatStrOrFunc)) { + return moment(value).format(dateFormatStrOrFunc); + } } - const { - format = 'dateTime', - nil = '', - options, - } = dateFormatKeyOrConfig as FormatDateConfig; + if (instanceOfFormatDateConfig(dateFormatKeyOrConfig)) { + const { format = 'dateTime', nil = '', options } = dateFormatKeyOrConfig; - const dateFormat = dateFormatAliases[format] || format; + const dateFormat = dateFormatAliases[format] || format; - if (isNil(value)) { - return nil; - } + if (isNil(value)) { + return nil; + } - if (isFunction(dateFormat)) { - return dateFormat(value, options); - } + if (isFunction(dateFormat)) { + return dateFormat(value, options); + } - return moment(value).format(dateFormat); + if (isString(dateFormat)) { + return moment(value).format(dateFormat); + } + } }; diff --git a/src/services/predicate/common_predicates.ts b/src/services/predicate/common_predicates.ts index 8101e17ef68..8b129d2b98a 100644 --- a/src/services/predicate/common_predicates.ts +++ b/src/services/predicate/common_predicates.ts @@ -4,15 +4,15 @@ export const always = (value?: any) => true; export const never = (value?: any) => false; -export const isUndefined = (value: any) => { +export const isUndefined = (value: any): value is undefined => { return value === undefined; }; -export const isNull = (value: any) => { +export const isNull = (value: any): value is null => { return value === null; }; -export const isNil = (value: any) => { +export const isNil = (value: any): value is null | undefined => { return isUndefined(value) || isNull(value); }; @@ -20,7 +20,7 @@ export const isMoment = (value: any) => { return moment.isMoment(value); }; -export const isDate = (value: any) => { +export const isDate = (value: any): value is Date => { return moment.isDate(value); }; diff --git a/src/services/predicate/lodash_predicates.ts b/src/services/predicate/lodash_predicates.ts index 168839c360d..be15edf12b0 100644 --- a/src/services/predicate/lodash_predicates.ts +++ b/src/services/predicate/lodash_predicates.ts @@ -9,7 +9,8 @@ import _isNaN from 'lodash/isNaN'; // exported, which can conflict with the lodash namespace if other versions are used // tslint:disable-next-line:ban-types -export const isFunction = (value: any): value is Function => _isFunction(value); +export const isFunction = (value: any): value is (...args: any[]) => any => + _isFunction(value); export const isArray = (value: any): value is any[] => _isArray(value); export const isString = (value: any): value is string => _isString(value); export const isBoolean = (value: any): value is boolean => _isBoolean(value); From 4640bcd7b523df0e8536952dee46c217b29b90b5 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 11 Apr 2019 16:13:06 -0500 Subject: [PATCH 4/5] clean up trial --- src/services/format/format_date.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/services/format/format_date.ts b/src/services/format/format_date.ts index 7fe977b35b8..cc802830d7c 100644 --- a/src/services/format/format_date.ts +++ b/src/services/format/format_date.ts @@ -82,10 +82,6 @@ export const formatDate = ( ? dateFormatAliases[dateFormatKeyOrConfig] : dateFormatKeyOrConfig; - if (isString(dateFormatStrOrFunc)) { - return moment(value).format(dateFormatStrOrFunc); - } - if (isFunction(dateFormatStrOrFunc)) { return dateFormatStrOrFunc(value, {}); } From 9d2a44369e995b8263b6ebbf5b531a4685994432 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Mon, 15 Apr 2019 10:24:21 -0500 Subject: [PATCH 5/5] #1814 changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f34e37c0c..4342412077c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ - Converted `EuiTitle` to TS ([#1810](https://github.com/elastic/eui/pull/1810)) - Added `adjustDateOnChange` prop to date pickers, enabling month and year changes to trigger `onChange` ([#1817](https://github.com/elastic/eui/pull/1817)) +**Breaking changes** + +- Removed transitional `keyOfStringsOnly` option from TypeScript configuration ([#1814](https://github.com/elastic/eui/pull/1814)) + ## [`9.9.1`](https://github.com/elastic/eui/tree/v9.9.1) - Re-enabled installation of `@elastic/eui` via npm ([#1811](https://github.com/elastic/eui/pull/1811))