I'm dealing with a component that throws a
'AddressAutofill' cannot be used as a JSX component.
It's an imported library (mapbox). And the details of the error are
'AddressAutofill' cannot be used as a JSX component.
Its type 'ForwardRefExoticComponent<AddressAutofillProps & RefAttributes<unknown>>' is not a valid JSX element type.
Type 'ForwardRefExoticComponent<AddressAutofillProps & RefAttributes<unknown>>' is not assignable to type '(props: any, deprecatedLegacyContext?: any) => ReactNode'.
Type 'ReactElement<any, string | JSXElementConstructor<any>> | null' is not assignable to type 'ReactNode'.
Type 'ReactElement<any, string | JSXElementConstructor<any>>' is not assignable to type 'ReactNode'.
Property 'children' is missing in type 'ReactElement<any, string | JSXElementConstructor<any>>' but required in type 'ReactPortal'.ts(2786)
I thought it would be best to solve this by using @ts-expect-error
// @ts-expect-error - 'AddressAutofill' cannot be used as a JSX component.
This worked locally, as in I can build my project just fine. In a github action though it fails
Unused '@ts-expect-error' directive.
I am aware that @ts-expect-error may throw that if I have misplaced the directive on something that doesn't actually have a TypeScript error.
But I don't know why it's not following that behavior locally like it does in the github action. I am using bun, here is the github action.
name: build
on:
push:
branches: [production, development]
pull_request:
branches: [production, development]
workflow_dispatch:
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: 'latest'
- name: Install dependencies
run: bun install
- name: Build
run: bun run build
Here is my tsconfig
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"strictNullChecks": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": [
"src",
"tailwind.config.js",
"vite.config.ts",
"src/types/*.d.ts"
],
"references": [{ "path": "./tsconfig.node.json" }]
}
And here's the code where I'm using the weird component and the @ts-expect-error directive
function AddressAutofillWrapper({
children,
form,
}: {
children: React.ReactNode
form: UseFormReturn<z.infer<typeof formSchema>, unknown, undefined>
}) {
return (
// AddressAutofill has weird typing, it is expected to work like this however (see https://docs.mapbox.com/mapbox-search-js/api/react/autofill/#addressautofill-example)
// @ts-expect-error - 'AddressAutofill' cannot be used as a JSX component.
<AddressAutofill
accessToken={config.MAP_ACCESS_TOKEN}
onRetrieve={(res) => {
const feature = res.features[0]
const address = feature.properties.full_address
if (!address) {
toast.error('An unknown error occurred')
return
}
form.setValue('address', address)
}}
browserAutofillEnabled={false}
>
{/* Once again, weird typing, see example in previous comment for reference */}
{/* @ts-expect-error - Type 'ReactNode' is not assignable to type 'ReactChild'.*/}
{children}
</AddressAutofill>
)
}