diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e3088f57d..423e5c16ab3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ No public interface changes since `12.0.0`. - Fixed `EuiCallOut` header icon alignment ([#2006](https://github.com/elastic/eui/pull/2006)) - Fixed `EuiInMemoryTable` sort value persistence through lifecycle updates ([#2035](https://github.com/elastic/eui/pull/2035)) - Fixed `EuiColorPicker` positioning and keyboard navigation in certain portal contexts ([#2038](https://github.com/elastic/eui/pull/2038)) +- Fixed proptype for `EuiCopy`'s `children` ([#2048](https://github.com/elastic/eui/pull/2048)) **Breaking changes** diff --git a/scripts/babel/proptypes-from-ts-props/index.js b/scripts/babel/proptypes-from-ts-props/index.js index 0f56ca34cd8..6871a8f33ad 100644 --- a/scripts/babel/proptypes-from-ts-props/index.js +++ b/scripts/babel/proptypes-from-ts-props/index.js @@ -163,6 +163,7 @@ function resolveIdentifierToPropTypes(node, state) { if (identifier.name === 'Array') return resolveArrayToPropTypes(node, state); if (identifier.name === 'MouseEventHandler') return buildPropTypePrimitiveExpression(types, 'func'); + if (identifier.name === 'Function') return buildPropTypePrimitiveExpression(types, 'func'); if (identifier.name === 'ExclusiveUnion') { // We use ExclusiveUnion at the top level to exclusively discriminate between types // propTypes itself must be an object so merge the union sets together as an intersection @@ -453,9 +454,13 @@ function getPropTypesForNode(node, optional, state) { // which don't translate to prop types. .filter(property => property.key != null) .map(property => { + const propertyPropType = property.type === 'TSMethodSignature' + ? getPropTypesForNode({ type: 'TSFunctionType' }, property.optional, state) + : getPropTypesForNode(property.typeAnnotation, property.optional, state); + const objectProperty = types.objectProperty( types.identifier(property.key.name || `"${property.key.value}"`), - getPropTypesForNode(property.typeAnnotation, property.optional, state) + propertyPropType ); if (property.leadingComments != null) { objectProperty.leadingComments = property.leadingComments.map(({ type, value }) => ({ type, value })); @@ -507,9 +512,13 @@ function getPropTypesForNode(node, optional, state) { // skip TS index signatures if (types.isTSIndexSignature(property)) return null; + const propertyPropType = property.type === 'TSMethodSignature' + ? getPropTypesForNode({ type: 'TSFunctionType' }, property.optional, state) + : getPropTypesForNode(property.typeAnnotation, property.optional, state); + const objectProperty = types.objectProperty( types.identifier(property.key.name || `"${property.key.value}"`), - getPropTypesForNode(property.typeAnnotation, property.optional, state) + propertyPropType ); if (property.leadingComments != null) { objectProperty.leadingComments = property.leadingComments.map(({ type, value }) => ({ type, value })); diff --git a/scripts/babel/proptypes-from-ts-props/index.test.js b/scripts/babel/proptypes-from-ts-props/index.test.js index 7896203f089..72215851ce1 100644 --- a/scripts/babel/proptypes-from-ts-props/index.test.js +++ b/scripts/babel/proptypes-from-ts-props/index.test.js @@ -223,6 +223,72 @@ FooComponent.propTypes = { }); + describe('function propTypes', () => { + + it('understands function props on interfaces', () => { + const result = transform( + ` +import React from 'react'; +interface IFooProps { + foo(): ReactElement; + bar?(arg: number): string; + fizz: Function; + buzz?: (arg: boolean) => string; +} +const FooComponent: React.SFC = () => { + return (
Hello World
); +}`, + babelOptions + ); + + expect(result.code).toBe(`import React from 'react'; +import PropTypes from "prop-types"; + +const FooComponent = () => { + return
Hello World
; +}; + +FooComponent.propTypes = { + foo: PropTypes.func.isRequired, + bar: PropTypes.func, + fizz: PropTypes.func.isRequired, + buzz: PropTypes.func +};`); + }); + + it('understands function props on types', () => { + const result = transform( + ` +import React from 'react'; +type FooProps = { + foo(): ReactElement; + bar?(arg: number): string; + fizz: Function; + buzz?: (arg: boolean) => string; +} +const FooComponent: React.SFC = () => { + return (
Hello World
); +}`, + babelOptions + ); + + expect(result.code).toBe(`import React from 'react'; +import PropTypes from "prop-types"; + +const FooComponent = () => { + return
Hello World
; +}; + +FooComponent.propTypes = { + foo: PropTypes.func.isRequired, + bar: PropTypes.func, + fizz: PropTypes.func.isRequired, + buzz: PropTypes.func +};`); + }); + + }); + describe('enum / oneOf propTypes', () => { describe('union type', () => {