From 4dd9510a504875fb79a399d468e8f39e892af617 Mon Sep 17 00:00:00 2001 From: Jessica Date: Fri, 23 Nov 2018 15:05:46 +0900 Subject: [PATCH] Strengthen type of ReactType to also validate intrinsic elements --- types/react/index.d.ts | 12 ++++++++---- types/react/test/tsx.tsx | 7 +++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/types/react/index.d.ts b/types/react/index.d.ts index 25f3c710ae..522a106944 100644 --- a/types/react/index.d.ts +++ b/types/react/index.d.ts @@ -50,7 +50,11 @@ declare namespace React { // React Elements // ---------------------------------------------------------------------- - type ReactType

= string | ComponentType

; + type ReactType

= + { + [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never + }[keyof JSX.IntrinsicElements] | + ComponentType

; type ComponentType

= ComponentClass

| FunctionComponent

; type Key = string | number; @@ -713,17 +717,17 @@ declare namespace React { * NOTE: prefer ComponentPropsWithRef, if the ref is forwarded, * or ComponentPropsWithoutRef when refs are not supported. */ - type ComponentProps> = + type ComponentProps = T extends ComponentType ? P : T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] : {}; - type ComponentPropsWithRef> = + type ComponentPropsWithRef = T extends ComponentClass ? PropsWithoutRef

& RefAttributes> : PropsWithRef>; - type ComponentPropsWithoutRef> = + type ComponentPropsWithoutRef = PropsWithoutRef>; // will show `Memo(${Component.displayName || Component.name})` in devtools by default, diff --git a/types/react/test/tsx.tsx b/types/react/test/tsx.tsx index f344fb2838..a8ca2ae1ea 100644 --- a/types/react/test/tsx.tsx +++ b/types/react/test/tsx.tsx @@ -325,3 +325,10 @@ 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