Type error in enonic component from getComponent (React4xp)

Enonic version: 7.13.3
OS: Ubuntu 20.04

Hi, I’m using React4xp and I’m just trying to get the config from a component like this:

const component = getComponent()
const componentConfig = component.config || {}

But I’m getting this typescript error on the .config:

Property ‘config’ does not exist on type ‘Component’.
Property ‘config’ does not exist on type ‘FragmentComponent’.ts(2339)

I’ve been just ignoring this for a while because everything seems to be working ok, but maybe this should get fixed?
Thank you.

How do you import getComponent? Are you using our type definitions from @enonic-types?

If you import getComponent like this:

import {getComponent} from '/lib/xp/portal';

then calling getComponent() will return an object of a generic Component type. It’s a union type of more specific types (see declaration here). It doesn’t have the config property, because not all component types have the config property: Page, Layout, Part do, while Text and Fragment don’t.

So, you cannot simply access the .config property, you need a type guard. If result of getComponent() is of either PageComponent or LayoutComponent or PartComponent type, then you can access it, otherwise not.

Oh, now I see that I have to import it from '@enonic-types/core', I wasn’t finding the PartComponent from the enonic-types because I didn’t know that. Thanks!

Since we are already discussing about typescript in react4xp, when I use log.info in my .ts controller file, I get Cannot find name 'log'.ts(2304) in the log variable. Is there a way to fix this too?

@ase @Cwe I think maybe the different types for components (PartComponent etc.) should be re-exported from "/lib/xp/portal" in the same way that Content is re-exported.

To use getComponent() in a meaningful way with TypeScript, you basically always have to import the correct Component type to use as a generic, so it would make architectural sense to be able to do that import from portal-lib.

current way:

import { getContent } from "/lib/xp/portal";
import type { PartComponent } from "@enonic-types/core";

as suggested above:

import { getContent, type PartComponent } from "/lib/xp/portal";

– Tom Arild

1 Like

Hi @reinaldoams ,

If you are using TypeScript in your project, you should checkout this gradle-plugin I made that generates TypeScript-types based on the XML-files in your project.

It integrates nicely with the TypeScript-types of XP (which I was involved in the making of).

Like in this case, it can now look up the shape of the component based on the string name of the type.

– Tom Arild

1 Like