Home > Back-end >  Typing React Namespaces
Typing React Namespaces

Time:09-30

I'm trying to figure out how to type react namespaces.

Currently, I have a component

import {Head} from "./head/head";
import {Body} from "./body/body";

interface Props {
  id: string
}

const Component:React.FC<Props> = ({id}) =>{
return <span>Hello World</span>
};

Component.Head = Head;
Component.Body = Body;

usage is something like

<Component>
 <Component.Head></Component.Head>
 <Component.Body></Component.Body>
</Component>

I keep getting this typing error

Property 'Head' does not exist on type 'FC'

What am I missing?

CodePudding user response:

Well you are saying that "Component" is of type React.FC. Meaning it has the properties / structure of the type defined in React.FC.

But, you then give Component two properties of Head and Body, which are not defined in the React.FC type.

Therefore, if you did want to do what you are trying in your code, you would need to define your own type that extends React.FC and expects both Head and Body properties.

type TypeNameHere<Props> = React.FC<Props> & {
  Head: *TypeOfWhateverHeadWillBeHere*;
  Body: *TypeOfWhateverBodyWillBeHere*;
};

You would then use this for the definition of Component

const Component:TypeNameHere<Props> = ....;

I'll provide a simpler example without React to showcase:

type TypeExample1 = (props: string) => void;

const Component:TypeExample1 = (name) => console.log(name);

Component.Head = 'Head here'; //Error: Property Head does not exist on type TypeExample1
Component.Body = 'Body here'; //Error: Property Body does not exist on type TypeExample1

The code above would result in the same error, because according to the definition of TypeExample1, it should just be a function that takes a string and returns nothing, without any properties of Head or Body.

Whereas, the code below would enable this to work by creating a new type TypeExample2 that extends TypeExample1 to also include properties for Head and Body:

type TypeExample1 = (props: string) => void;

type TypeExample2 = TypeExample1 & {Head: string; Body: string;}

const Component:TypeExample2 = (name) => console.log(name);


Component.Head = 'Head here';
Component.Body = 'Body here';

Hope that helps!

  • Related