-
Notifications
You must be signed in to change notification settings - Fork 51
fix: names of mapped props for shorthand factories #591
Changes from all commits
c21d3b5
3be332a
349353b
ca2d2f0
9ed5929
595b576
ee50266
f4a4daf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,42 @@ | ||
| import * as React from 'react' | ||
| import { mountWithProvider as mount } from 'test/utils' | ||
| import * as _ from 'lodash' | ||
| import { PropsOf } from 'types/utils' | ||
|
|
||
| export type CollectionShorthandTestOptions = { | ||
| mapsValueToProp?: string | ||
| skipArrayOfStrings?: boolean | ||
| export type CollectionShorthandTestOptions<TProps = any> = { | ||
| mapsValueToProp: keyof (TProps & React.HTMLProps<HTMLElement>) | false | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 for adding the false value as a option! |
||
| } | ||
|
|
||
| export const DefaultCollectionShorthandTestOptions: CollectionShorthandTestOptions = { | ||
| mapsValueToProp: 'content', | ||
| skipArrayOfStrings: false, | ||
| } | ||
|
|
||
| export default Component => { | ||
| export type CollectionShorthandPropTestsRunner<TComponent> = < | ||
| TShorthandComponent extends React.ComponentType | ||
| >( | ||
| shorthandProp: keyof PropsOf<TComponent>, | ||
| ShorthandComponent: TShorthandComponent, | ||
| options?: CollectionShorthandTestOptions<PropsOf<TShorthandComponent>>, | ||
| ) => any | ||
|
|
||
| export type CollectionShorthandPropTestsFactory = <TComponent extends React.ComponentType>( | ||
| Component: TComponent, | ||
| ) => CollectionShorthandPropTestsRunner<TComponent> | ||
|
|
||
| export default ((Component: React.ComponentType) => { | ||
| return function implementsCollectionShorthandProp( | ||
| shorthandPropertyName: string, | ||
| ShorthandComponent: React.ComponentType, | ||
| options: CollectionShorthandTestOptions = DefaultCollectionShorthandTestOptions, | ||
| ) { | ||
| const { mapsValueToProp } = options | ||
| const mapsValueToProp = options.mapsValueToProp as string | ||
|
|
||
| describe(`shorthand property for '${ShorthandComponent.displayName}'`, () => { | ||
| test(`is defined`, () => { | ||
| expect(Component.propTypes[shorthandPropertyName]).toBeTruthy() | ||
| }) | ||
|
|
||
| if (!options.skipArrayOfStrings) { | ||
| if (options.mapsValueToProp) { | ||
| test(`array of string values is spread as ${ | ||
| ShorthandComponent.displayName | ||
| }s' ${mapsValueToProp}`, () => { | ||
|
|
@@ -73,4 +84,4 @@ export default Component => { | |
| }) | ||
| }) | ||
| } | ||
| } | ||
| }) as CollectionShorthandPropTestsFactory | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,17 @@ export type Props = ObjectOf<any> | |
| export type ReactChildren = React.ReactNodeArray | React.ReactNode | ||
| export type ComponentEventHandler<TProps> = (event: React.SyntheticEvent, data: TProps) => void | ||
|
|
||
| type ChildrenProps = { children: any } | ||
| export type PropsOf<T> = T extends React.ComponentClass<Extendable<infer TProps>> | ||
| ? (ChildrenProps & TProps) | ||
| : T extends React.ComponentClass<infer TProps> | ||
| ? (ChildrenProps & TProps) | ||
| : T extends React.StatelessComponent<Extendable<infer TProps>> | ||
| ? (ChildrenProps & TProps) | ||
| : T extends React.StatelessComponent<infer TProps> | ||
| ? (ChildrenProps & TProps) | ||
| : any | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This type looks like a pure evil 😈 We had a similar issue before and I solved it with a generic type: export function createShorthandFactory<P>(
Component: React.ReactType<P>,
mappedProp?: keyof P & string, // `string` may be redundant there
) {Yes, we should update all files, but this type check is much simpler and obvious.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the suggested approach
I don't think that this type looks unreadable - actually, am pretty sure that any At the same time, I've intentionally made these changes to be unobtrusive - you might notice that I've affected public interfaces of the methods only, without touching the actual types that were used before inside of the methods. Have done this intentionally, to be sure that this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, this is, actually, from the TS docs: https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#generic-rest-parameters type Unpacked<T> =
T extends (infer U)[] ? U :
T extends (...args: any[]) => infer U ? U :
T extends Promise<infer U> ? U :
T;don't get me wrong - I would be glad to use simpler expression to achieve the same goal (and opened to any suggestions), just now see it as the only (reliable) solution available to us
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, and now, probably, see another reason for your point (apart from the general one) - thing is that I've used another formatting initially: T extends React.ComponentClass<Extendable<infer TProps>> ? (ChildrenProps & TProps)
: T extends React.ComponentClass<infer TProps> ? (ChildrenProps & TProps)
: T extends React.StatelessComponent<Extendable<infer TProps>> ? (ChildrenProps & TProps)
: T extends React.StatelessComponent<infer TProps> ? (ChildrenProps & TProps)
: anyThis was easier to read - but now, with the prettier changes it becomes absolutely cryptic. Will try to address this readability issue
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've tested this myself locally too. @layershifter your proposal works, but as you mention we will need to update all createShorthandFactory usages, if we want to leverage this. If we forget to do this, we may still have the previous errors. @kuzhelov 's suggested typings don't require this from the user, and offer out of the box checking for this. I see this as a better alternative and big improvement step. I vote for the typings implemented in the PR.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mnajdova I agree and fully support improvals there, but how much time do you need to understand what is happening in there? To be honest, can you say that this type is a simple and obvious?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not saying it is simple and obvious, but I don't think that just because it is not simple, we should not add it. Improving our skills and knowledge will mean we will start adding more complicated typings, and I am totally supporting that. @kuzhelov maybe just short description above the type will help others to better understand it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is insane! 👍
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have tried alternative options, but all of them require type inference and, thus, the same amount of |
||
|
|
||
| // ======================================================== | ||
| // Shorthand Factories | ||
| // ======================================================== | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍