From 5f9b376456e9926c0edfef6c8604ec9f5d926dd5 Mon Sep 17 00:00:00 2001 From: frezc <504021398@qq.com> Date: Sat, 22 Dec 2018 21:21:42 +0800 Subject: [PATCH] [type] make type of components compatible with ComponentType

--- components/_util/type.ts | 2 ++ components/avatar/index.tsx | 4 ++-- components/button/button.tsx | 21 +++++++++++++-------- components/calendar/index.tsx | 4 ++-- components/drawer/index.tsx | 11 ++++++----- components/dropdown/dropdown-button.tsx | 8 +++++--- components/dropdown/dropdown.tsx | 14 ++++++++++++-- components/form/Form.tsx | 7 ++++--- components/form/FormItem.tsx | 7 +++++-- components/grid/col.tsx | 11 +++++------ components/grid/row.tsx | 14 ++++++++------ components/input/Input.tsx | 12 +++++++----- components/list/Item.tsx | 12 ------------ components/list/index.tsx | 4 ++-- components/mention/index.tsx | 2 +- components/modal/Modal.tsx | 4 ++-- components/popconfirm/index.tsx | 6 +++--- components/progress/progress.tsx | 15 +++++++++------ components/select/index.tsx | 7 +++++-- components/spin/index.tsx | 8 +++++--- components/switch/index.tsx | 4 +++- components/table/Table.tsx | 2 +- components/tabs/index.tsx | 2 +- components/transfer/index.tsx | 7 ++++--- 24 files changed, 107 insertions(+), 81 deletions(-) diff --git a/components/_util/type.ts b/components/_util/type.ts index 3e4c505231..9805d62cc9 100644 --- a/components/_util/type.ts +++ b/components/_util/type.ts @@ -1 +1,3 @@ export type Omit = Pick>; +// https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead +export const tuple = (...args: T) => args; \ No newline at end of file diff --git a/components/avatar/index.tsx b/components/avatar/index.tsx index 4e3eadd392..385cd4e5de 100644 --- a/components/avatar/index.tsx +++ b/components/avatar/index.tsx @@ -35,8 +35,8 @@ export interface AvatarState { export default class Avatar extends React.Component { static defaultProps = { prefixCls: 'ant-avatar', - shape: 'circle', - size: 'default', + shape: 'circle' as AvatarProps['shape'], + size: 'default' as AvatarProps['size'], }; state = { diff --git a/components/button/button.tsx b/components/button/button.tsx index dbddfa262b..9dc0c75f32 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -4,6 +4,7 @@ import classNames from 'classnames'; import Wave from '../_util/wave'; import Icon from '../icon'; import Group from './button-group'; +import { tuple } from '../_util/type'; const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); @@ -36,10 +37,14 @@ function insertSpace(child: React.ReactChild, needInserted: boolean) { return child; } -export type ButtonType = 'default' | 'primary' | 'ghost' | 'dashed' | 'danger'; -export type ButtonShape = 'circle' | 'circle-outline'; -export type ButtonSize = 'small' | 'default' | 'large'; -export type ButtonHTMLType = 'submit' | 'button' | 'reset'; +const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger'); +export type ButtonType = (typeof ButtonTypes)[number]; +const ButtonShapes = tuple('circle', 'circle-outline'); +export type ButtonShape = (typeof ButtonShapes)[number]; +const ButtonSizes = tuple('large', 'default', 'small'); +export type ButtonSize = (typeof ButtonSizes)[number]; +const ButtonHTMLTypes = tuple('submit', 'button', 'reset'); +export type ButtonHTMLType = (typeof ButtonHTMLTypes)[number]; export interface BaseButtonProps { type?: ButtonType; @@ -81,10 +86,10 @@ export default class Button extends React.Component { }; static propTypes = { - type: PropTypes.string, - shape: PropTypes.oneOf(['circle', 'circle-outline']), - size: PropTypes.oneOf(['large', 'default', 'small']), - htmlType: PropTypes.oneOf(['submit', 'button', 'reset']), + type: PropTypes.oneOf(ButtonTypes), + shape: PropTypes.oneOf(ButtonShapes), + size: PropTypes.oneOf(ButtonSizes), + htmlType: PropTypes.oneOf(ButtonHTMLTypes), onClick: PropTypes.func, loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), className: PropTypes.string, diff --git a/components/calendar/index.tsx b/components/calendar/index.tsx index 63137acd5a..30113fb2ac 100644 --- a/components/calendar/index.tsx +++ b/components/calendar/index.tsx @@ -53,7 +53,7 @@ export default class Calendar extends React.Component, onSelect: PropTypes.func, onChange: PropTypes.func, }; diff --git a/components/drawer/index.tsx b/components/drawer/index.tsx index 6ace8c0775..58bc6c4984 100644 --- a/components/drawer/index.tsx +++ b/components/drawer/index.tsx @@ -5,6 +5,7 @@ import createReactContext, { Context } from 'create-react-context'; import warning from 'warning'; import classNames from 'classnames'; import Icon from '../icon'; +import { tuple } from '../_util/type'; const DrawerContext: Context = createReactContext(null); @@ -12,7 +13,8 @@ type EventType = React.MouseEvent | React.MouseEvent HTMLElement; -type placementType = 'top' | 'right' | 'bottom' | 'left'; +const PlacementTypes = tuple('top', 'right', 'bottom', 'left'); +type placementType = (typeof PlacementTypes)[number]; export interface DrawerProps { closable?: boolean; destroyOnClose?: boolean; @@ -45,9 +47,8 @@ export default class Drawer extends React.Component { destroyOnClose: PropTypes.bool, getContainer: PropTypes.oneOfType([ PropTypes.string, - PropTypes.object, + PropTypes.object as PropTypes.Requireable, PropTypes.func, - PropTypes.bool, ]), maskClosable: PropTypes.bool, mask: PropTypes.bool, @@ -58,7 +59,7 @@ export default class Drawer extends React.Component { width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), zIndex: PropTypes.number, prefixCls: PropTypes.string, - placement: PropTypes.string, + placement: PropTypes.oneOf(PlacementTypes), onClose: PropTypes.func, className: PropTypes.string, }; @@ -68,7 +69,7 @@ export default class Drawer extends React.Component { width: 256, height: 256, closable: true, - placement: 'right', + placement: 'right' as placementType, maskClosable: true, mask: true, level: null, diff --git a/components/dropdown/dropdown-button.tsx b/components/dropdown/dropdown-button.tsx index fb5a040b9a..47eff9a5aa 100644 --- a/components/dropdown/dropdown-button.tsx +++ b/components/dropdown/dropdown-button.tsx @@ -7,8 +7,10 @@ import Dropdown, { DropDownProps } from './dropdown'; import classNames from 'classnames'; const ButtonGroup = Button.Group; +type DropdownButtonType = 'primary' | 'ghost' | 'dashed'; + export interface DropdownButtonProps extends ButtonGroupProps, DropDownProps { - type?: 'primary' | 'ghost' | 'dashed'; + type?: DropdownButtonType; htmlType?: ButtonHTMLType; disabled?: boolean; onClick?: React.MouseEventHandler; @@ -17,8 +19,8 @@ export interface DropdownButtonProps extends ButtonGroupProps, DropDownProps { export default class DropdownButton extends React.Component { static defaultProps = { - placement: 'bottomRight', - type: 'default', + placement: 'bottomRight' as DropDownProps['placement'], + type: 'default' as DropdownButtonType, prefixCls: 'ant-dropdown-button', }; diff --git a/components/dropdown/dropdown.tsx b/components/dropdown/dropdown.tsx index 766a66abdd..f628e159e2 100644 --- a/components/dropdown/dropdown.tsx +++ b/components/dropdown/dropdown.tsx @@ -5,7 +5,17 @@ import DropdownButton from './dropdown-button'; import { ConfigConsumer, ConfigProviderProps } from '../config-provider'; import warning from '../_util/warning'; import Icon from '../icon'; +import { tuple } from '../_util/type'; +const Placements = tuple( + 'topLeft', + 'topCenter', + 'topRight', + 'bottomLeft', + 'bottomCenter', + 'bottomRight', +); +type Placement = (typeof Placements)[number]; export interface DropDownProps { trigger?: ('click' | 'hover' | 'contextMenu')[]; overlay: React.ReactNode; @@ -17,7 +27,7 @@ export interface DropDownProps { prefixCls?: string; className?: string; transitionName?: string; - placement?: 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight'; + placement?: Placement; overlayClassName?: string; overlayStyle?: React.CSSProperties; forceRender?: boolean; @@ -31,7 +41,7 @@ export default class Dropdown extends React.Component { prefixCls: 'ant-dropdown', mouseEnterDelay: 0.15, mouseLeaveDelay: 0.1, - placement: 'bottomLeft', + placement: 'bottomLeft' as Placement, }; getTransitionName() { diff --git a/components/form/Form.tsx b/components/form/Form.tsx index 3b3600ccdc..1120e60a33 100755 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -7,7 +7,7 @@ import omit from 'omit.js'; import warning from '../_util/warning'; import FormItem from './FormItem'; import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants'; -import { Omit } from '../_util/type'; +import { Omit, tuple } from '../_util/type'; type FormCreateOptionMessagesCallback = (...args: any[]) => string; @@ -23,7 +23,8 @@ export interface FormCreateOption { withRef?: boolean; } -export type FormLayout = 'horizontal' | 'inline' | 'vertical'; +const FormLayouts = tuple('horizontal', 'inline', 'vertical'); +export type FormLayout = (typeof FormLayouts)[number]; export interface FormProps extends React.FormHTMLAttributes { layout?: FormLayout; @@ -161,7 +162,7 @@ export default class Form extends React.Component { static propTypes = { prefixCls: PropTypes.string, - layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']), + layout: PropTypes.oneOf(FormLayouts), children: PropTypes.any, onSubmit: PropTypes.func, hideRequiredMark: PropTypes.bool, diff --git a/components/form/FormItem.tsx b/components/form/FormItem.tsx index ae2552eca0..a3a6520388 100644 --- a/components/form/FormItem.tsx +++ b/components/form/FormItem.tsx @@ -9,6 +9,9 @@ import Col, { ColProps } from '../grid/col'; import warning from '../_util/warning'; import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants'; import Icon from '../icon'; +import { tuple } from '../_util/type'; + +const ValidateStatuses = tuple('success', 'warning', 'error', 'validating'); export interface FormItemProps { prefixCls?: string; @@ -19,7 +22,7 @@ export interface FormItemProps { wrapperCol?: ColProps; help?: React.ReactNode; extra?: React.ReactNode; - validateStatus?: 'success' | 'warning' | 'error' | 'validating'; + validateStatus?: (typeof ValidateStatuses)[number]; hasFeedback?: boolean; required?: boolean; style?: React.CSSProperties; @@ -42,7 +45,7 @@ export default class FormItem extends React.Component { label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), labelCol: PropTypes.object, help: PropTypes.oneOfType([PropTypes.node, PropTypes.bool]), - validateStatus: PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']), + validateStatus: PropTypes.oneOf(ValidateStatuses), hasFeedback: PropTypes.bool, wrapperCol: PropTypes.object, className: PropTypes.string, diff --git a/components/grid/col.tsx b/components/grid/col.tsx index 74ffe80add..e6136fddef 100644 --- a/components/grid/col.tsx +++ b/components/grid/col.tsx @@ -3,7 +3,6 @@ import * as PropTypes from 'prop-types'; import classNames from 'classnames'; import RowContext from './RowContext'; -const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]); export interface ColSize { @@ -31,11 +30,11 @@ export interface ColProps extends React.HTMLAttributes { export default class Col extends React.Component { static propTypes = { - span: stringOrNumber, - order: stringOrNumber, - offset: stringOrNumber, - push: stringOrNumber, - pull: stringOrNumber, + span: PropTypes.number, + order: PropTypes.number, + offset: PropTypes.number, + push: PropTypes.number, + pull: PropTypes.number, className: PropTypes.string, children: PropTypes.node, xs: objectOrNumber, diff --git a/components/grid/row.tsx b/components/grid/row.tsx index 89c28efe7b..aae8f4f242 100644 --- a/components/grid/row.tsx +++ b/components/grid/row.tsx @@ -18,15 +18,17 @@ import * as React from 'react'; import classNames from 'classnames'; import * as PropTypes from 'prop-types'; import RowContext from './RowContext'; +import { tuple } from '../_util/type'; export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type BreakpointMap = Partial>; - +const RowAligns = tuple('top', 'middle', 'bottom'); +const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between'); export interface RowProps extends React.HTMLAttributes { gutter?: number | Partial>; type?: 'flex'; - align?: 'top' | 'middle' | 'bottom'; - justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between'; + align?: (typeof RowAligns)[number]; + justify?: (typeof RowJustify)[number]; prefixCls?: string; } @@ -51,9 +53,9 @@ export default class Row extends React.Component { }; static propTypes = { - type: PropTypes.string, - align: PropTypes.string, - justify: PropTypes.string, + type: PropTypes.oneOf<'flex'>(['flex']), + align: PropTypes.oneOf(RowAligns), + justify: PropTypes.oneOf(RowJustify), className: PropTypes.string, children: PropTypes.node, gutter: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), diff --git a/components/input/Input.tsx b/components/input/Input.tsx index 84ea64039b..b2fa9f6a34 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -5,7 +5,7 @@ import omit from 'omit.js'; import Group from './Group'; import Search from './Search'; import TextArea from './TextArea'; -import { Omit } from '../_util/type'; +import { Omit, tuple } from '../_util/type'; function fixControlledValue(value: T) { if (typeof value === 'undefined' || value === null) { @@ -14,10 +14,12 @@ function fixControlledValue(value: T) { return value; } +const InputSizes = tuple('small', 'default', 'large'); + export interface InputProps extends Omit, 'size' | 'prefix'> { prefixCls?: string; - size?: 'large' | 'default' | 'small'; + size?: (typeof InputSizes)[number]; onPressEnter?: React.KeyboardEventHandler; addonBefore?: React.ReactNode; addonAfter?: React.ReactNode; @@ -38,9 +40,9 @@ export default class Input extends React.Component { static propTypes = { type: PropTypes.string, - id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - size: PropTypes.oneOf(['small', 'default', 'large']), - maxLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + id: PropTypes.string, + size: PropTypes.oneOf(InputSizes), + maxLength: PropTypes.number, disabled: PropTypes.bool, value: PropTypes.any, defaultValue: PropTypes.any, diff --git a/components/list/Item.tsx b/components/list/Item.tsx index f8fcff7dd1..3910aa54b7 100644 --- a/components/list/Item.tsx +++ b/components/list/Item.tsx @@ -48,21 +48,9 @@ function getGrid(grid: ListGridType, t: ColumnType) { return grid[t] && Math.floor(24 / grid[t]!); } -const GridColumns = ['', 1, 2, 3, 4, 6, 8, 12, 24]; - export default class Item extends React.Component { static Meta: typeof Meta = Meta; - static propTypes = { - column: PropTypes.oneOf(GridColumns), - xs: PropTypes.oneOf(GridColumns), - sm: PropTypes.oneOf(GridColumns), - md: PropTypes.oneOf(GridColumns), - lg: PropTypes.oneOf(GridColumns), - xl: PropTypes.oneOf(GridColumns), - xxl: PropTypes.oneOf(GridColumns), - }; - static contextTypes = { grid: PropTypes.any, }; diff --git a/components/list/index.tsx b/components/list/index.tsx index 4c17d55b64..9f5ab9c02b 100644 --- a/components/list/index.tsx +++ b/components/list/index.tsx @@ -41,7 +41,7 @@ export interface ListProps { itemLayout?: string; loading?: boolean | SpinProps; loadMore?: React.ReactNode; - pagination?: PaginationConfig; + pagination?: PaginationConfig | false; prefixCls?: string; rowKey?: any; renderItem: any; @@ -69,7 +69,7 @@ export default class List extends React.Component { bordered: false, split: true, loading: false, - pagination: false, + pagination: false as ListProps['pagination'], }; state = { diff --git a/components/mention/index.tsx b/components/mention/index.tsx index 9b5d5f32d6..45fc4c2069 100644 --- a/components/mention/index.tsx +++ b/components/mention/index.tsx @@ -42,7 +42,7 @@ class Mention extends React.Component { notFoundContent: '无匹配结果,轻敲空格完成输入', loading: false, multiLines: false, - placement: 'bottom', + placement: 'bottom' as MentionPlacement, }; static Nav = Nav; static toString = toString; diff --git a/components/modal/Modal.tsx b/components/modal/Modal.tsx index 991ebe70d5..d32e0e746d 100644 --- a/components/modal/Modal.tsx +++ b/components/modal/Modal.tsx @@ -123,8 +123,8 @@ export default class Modal extends React.Component { prefixCls: PropTypes.string, onOk: PropTypes.func, onCancel: PropTypes.func, - okText: PropTypes.node, - cancelText: PropTypes.node, + okText: PropTypes.string, + cancelText: PropTypes.string, centered: PropTypes.bool, width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), confirmLoading: PropTypes.bool, diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index 0d9bb1f7d8..1501338075 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -33,9 +33,9 @@ class Popconfirm extends React.Component { static defaultProps = { prefixCls: 'ant-popover', transitionName: 'zoom-big', - placement: 'top', - trigger: 'click', - okType: 'primary', + placement: 'top' as PopconfirmProps['placement'], + trigger: 'click' as PopconfirmProps['trigger'], + okType: 'primary' as PopconfirmProps['okType'], icon: , }; diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx index 5c81f168d9..68b8499106 100644 --- a/components/progress/progress.tsx +++ b/components/progress/progress.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import Icon from '../icon'; import { Circle } from 'rc-progress'; import classNames from 'classnames'; +import { tuple } from '../_util/type'; const statusColorMap: Record = { normal: '#108ee9', @@ -10,7 +11,9 @@ const statusColorMap: Record = { success: '#87d068', }; -export type ProgressType = 'line' | 'circle' | 'dashboard'; +const ProgressTypes = tuple('line', 'circle', 'dashboard'); +export type ProgressType = (typeof ProgressTypes)[number]; +const ProgressStatuses = tuple('normal', 'exception', 'active', 'success'); export type ProgressSize = 'default' | 'small'; export interface ProgressProps { @@ -20,7 +23,7 @@ export interface ProgressProps { percent?: number; successPercent?: number; format?: (percent?: number, successPercent?: number) => React.ReactNode; - status?: 'success' | 'active' | 'exception' | 'normal'; + status?: (typeof ProgressStatuses)[number]; showInfo?: boolean; strokeWidth?: number; strokeLinecap?: string; @@ -44,17 +47,17 @@ const validProgress = (progress: number | undefined) => { export default class Progress extends React.Component { static defaultProps = { - type: 'line', + type: 'line' as ProgressProps['type'], percent: 0, showInfo: true, trailColor: '#f3f3f3', prefixCls: 'ant-progress', - size: 'default', + size: 'default' as ProgressSize, }; static propTypes = { - status: PropTypes.oneOf(['normal', 'exception', 'active', 'success']), - type: PropTypes.oneOf(['line', 'circle', 'dashboard']), + status: PropTypes.oneOf(ProgressStatuses), + type: PropTypes.oneOf(ProgressTypes), showInfo: PropTypes.bool, percent: PropTypes.number, width: PropTypes.number, diff --git a/components/select/index.tsx b/components/select/index.tsx index 5b6896a821..a3f9969456 100755 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -8,12 +8,15 @@ import { ConfigConsumer, ConfigProviderProps } from '../config-provider'; import omit from 'omit.js'; import warning from 'warning'; import Icon from '../icon'; +import { tuple } from '../_util/type'; + +const SelectSizes = tuple('default', 'large', 'small'); export interface AbstractSelectProps { prefixCls?: string; className?: string; showAction?: string | string[]; - size?: 'default' | 'large' | 'small'; + size?: (typeof SelectSizes)[number]; notFoundContent?: React.ReactNode | null; transitionName?: string; choiceTransitionName?: string; @@ -97,7 +100,7 @@ export interface SelectLocale { const SelectPropTypes = { prefixCls: PropTypes.string, className: PropTypes.string, - size: PropTypes.oneOf(['default', 'large', 'small']), + size: PropTypes.oneOf(SelectSizes), notFoundContent: PropTypes.any, showSearch: PropTypes.bool, optionLabelProp: PropTypes.string, diff --git a/components/spin/index.tsx b/components/spin/index.tsx index 63aaeaf43a..56eab0393f 100644 --- a/components/spin/index.tsx +++ b/components/spin/index.tsx @@ -2,8 +2,10 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import classNames from 'classnames'; import omit from 'omit.js'; +import { tuple } from '../_util/type'; -export type SpinSize = 'small' | 'default' | 'large'; +const SpinSizes = tuple('small', 'default', 'large'); +export type SpinSize = (typeof SpinSizes)[number]; export type SpinIndicator = React.ReactElement; export interface SpinProps { @@ -67,9 +69,9 @@ class Spin extends React.Component { prefixCls: PropTypes.string, className: PropTypes.string, spinning: PropTypes.bool, - size: PropTypes.oneOf(['small', 'default', 'large']), + size: PropTypes.oneOf(SpinSizes), wrapperClassName: PropTypes.string, - indicator: PropTypes.node, + indicator: PropTypes.element, }; static setDefaultIndicator(indicator: React.ReactNode) { diff --git a/components/switch/index.tsx b/components/switch/index.tsx index 78c006b484..2e9134a9eb 100755 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -30,7 +30,9 @@ export default class Switch extends React.Component { prefixCls: PropTypes.string, // HACK: https://github.com/ant-design/ant-design/issues/5368 // size=default and size=large are the same - size: PropTypes.oneOf(['small', 'default', 'large']), + size: PropTypes.oneOf(['small', 'default', 'large']) as PropTypes.Requireable< + SwitchProps['size'] + >, className: PropTypes.string, }; diff --git a/components/table/Table.tsx b/components/table/Table.tsx index 3f636bb6ec..c05bce45e8 100755 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -75,7 +75,7 @@ export default class Table extends React.Component, TableState< useFixedHeader: PropTypes.bool, rowSelection: PropTypes.object, className: PropTypes.string, - size: PropTypes.string, + size: PropTypes.string as PropTypes.Requireable, loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), bordered: PropTypes.bool, onChange: PropTypes.func, diff --git a/components/tabs/index.tsx b/components/tabs/index.tsx index 61ad53f9ba..57eb08440c 100755 --- a/components/tabs/index.tsx +++ b/components/tabs/index.tsx @@ -51,7 +51,7 @@ export default class Tabs extends React.Component { static defaultProps = { prefixCls: 'ant-tabs', hideAdd: false, - tabPosition: 'top', + tabPosition: 'top' as TabsPosition, }; removeTab = (targetKey: string, e: React.MouseEvent) => { diff --git a/components/transfer/index.tsx b/components/transfer/index.tsx index 2fa3bb8efe..6bda521a4d 100644 --- a/components/transfer/index.tsx +++ b/components/transfer/index.tsx @@ -15,6 +15,7 @@ export { TransferSearchProps } from './search'; function noop() {} export type TransferDirection = 'left' | 'right'; +type TransferRender = (record: TransferItem) => React.ReactNode; export interface TransferItem { key: string; @@ -30,7 +31,7 @@ export interface TransferProps { dataSource: TransferItem[]; targetKeys?: string[]; selectedKeys?: string[]; - render?: (record: TransferItem) => React.ReactNode; + render?: TransferRender; onChange?: (targetKeys: string[], direction: string, moveKeys: any) => void; onSelectChange?: (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => void; style?: React.CSSProperties; @@ -68,7 +69,7 @@ export default class Transfer extends React.Component { static defaultProps = { dataSource: [], - render: noop, + render: noop as TransferRender, locale: {}, showSearch: false, }; @@ -76,7 +77,7 @@ export default class Transfer extends React.Component { static propTypes = { prefixCls: PropTypes.string, disabled: PropTypes.bool, - dataSource: PropTypes.array, + dataSource: PropTypes.array as PropTypes.Validator, render: PropTypes.func, targetKeys: PropTypes.array, onChange: PropTypes.func,