Merge pull request #30764 from Kovensky/react-react-type

Strengthen type of ReactType to also validate intrinsic elements
This commit is contained in:
Mine Starks
2018-11-28 19:24:53 -08:00
committed by GitHub
4 changed files with 33 additions and 9 deletions
+1 -1
View File
@@ -125,7 +125,7 @@ export default class ScrollableTabView extends React.Component<ScrollableTabView
// Each top-level child component should have a tabLabel prop
// that can be used by the tab bar component to render out the labels.
export type TabProps<T = {}> = T & {
tabLabel: React.ReactType;
tabLabel: React.ReactChild;
};
export interface DefaultTabBarProps {
@@ -43,14 +43,14 @@ function testInstance(inst: ReactTestInstance) {
inst.props = {
prop1: "p",
};
inst.type = "t";
testInstance(inst.find(n => n.type === "t"));
inst.type = "a";
testInstance(inst.find(n => n.type === "a"));
testInstance(inst.findByProps({ prop1: "p" }));
testInstance(inst.findByType("t"));
testInstance(inst.findByType("a"));
testInstance(inst.findByType(TestComponent));
inst.findAll(n => n.type === "t", { deep: true }).map(testInstance);
inst.findAllByProps({ prop1: "p" }, { deep: true }).map(testInstance);
inst.findAllByType("t", { deep: true }).map(testInstance);
inst.findAllByType("a", { deep: true }).map(testInstance);
inst.findAllByType(TestComponent, { deep: true }).map(testInstance);
}
+8 -4
View File
@@ -49,7 +49,11 @@ declare namespace React {
// React Elements
// ----------------------------------------------------------------------
type ReactType<P = any> = string | ComponentType<P>;
type ReactType<P = any> =
{
[K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never
}[keyof JSX.IntrinsicElements] |
ComponentType<P>;
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
type Key = string | number;
@@ -712,17 +716,17 @@ declare namespace React {
* NOTE: prefer ComponentPropsWithRef, if the ref is forwarded,
* or ComponentPropsWithoutRef when refs are not supported.
*/
type ComponentProps<T extends keyof JSX.IntrinsicElements | ComponentType<any>> =
type ComponentProps<T extends ReactType> =
T extends ComponentType<infer P>
? P
: T extends keyof JSX.IntrinsicElements
? JSX.IntrinsicElements[T]
: {};
type ComponentPropsWithRef<T extends keyof JSX.IntrinsicElements | ComponentType<any>> =
type ComponentPropsWithRef<T extends ReactType> =
T extends ComponentClass<infer P>
? PropsWithoutRef<P> & RefAttributes<InstanceType<T>>
: PropsWithRef<ComponentProps<T>>;
type ComponentPropsWithoutRef<T extends keyof JSX.IntrinsicElements | ComponentType<any>> =
type ComponentPropsWithoutRef<T extends ReactType> =
PropsWithoutRef<ComponentProps<T>>;
// will show `Memo(${Component.displayName || Component.name})` in devtools by default,
+20
View File
@@ -325,3 +325,23 @@ type ImgPropsWithRefRef = ImgPropsWithRef['ref'];
type ImgPropsWithoutRef = React.ComponentPropsWithoutRef<'img'>;
// $ExpectType false
type ImgPropsHasRef = 'ref' extends keyof ImgPropsWithoutRef ? true : false;
const HasClassName: React.ReactType<{ className?: string }> = 'a';
const HasFoo: React.ReactType<{ foo: boolean }> = 'a'; // $ExpectError
const HasFoo2: React.ReactType<{ foo: boolean }> = (props: { foo: boolean }) => null;
const HasFoo3: React.ReactType<{ foo: boolean }> = (props: { foo: string }) => null; // $ExpectError
const HasHref: React.ReactType<{ href?: string }> = 'a';
const HasHref2: React.ReactType<{ href?: string }> = 'div'; // $ExpectError
const CustomElement: React.ReactType = 'my-undeclared-element'; // $ExpectError
// custom elements now need to be declared as intrinsic elements
declare global {
namespace JSX {
interface IntrinsicElements {
'my-declared-element': {};
}
}
}
const CustomElement2: React.ReactType = 'my-declared-element';