Closed4

@react-three/drei と ChakraUI を使うと発生する TypeScript の型エラーを解決したい

r4air4ai

Error code

Run yarn export
yarn run v1.22.19
$ next build && next export && next-export-optimize-images
info - [next-export-optimize-images]: Configuration was not loaded. (This is optional.)
warn  - You have enabled experimental feature (esmExternals) in next.config.js.
warn  - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.

warn  - No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

info  - Linting and checking validity of types...
Failed to compile.

./src/components/common/Header.tsx:13:9
Type error: Expression produces a union type that is too complex to represent.

  11 |     <>
  12 |       <Flex
> 13 |         bgColor={colorMode === 'light' ? 'blackAlpha.100' : 'blackAlpha.400'}
     |         ^
  14 |         {...props}
  15 |         top={0}
  16 |         zIndex='sticky'
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

https://github.com/r4ai/r4ai.github.io/actions/runs/3801495222/jobs/6466025267

原因

@react-three/dreiをinstallした状態で、次のようにpropsをスプレッド構文で渡すとエラーが起きる。尚、@react-three/dreiを削除したらこのエラーは消えた。
一見 three.js とは無関係のコードなのに、なぜこのような事が起きるのか謎。

import { Link, LinkProps } from '@chakra-ui/react'
import NextLink from 'next/link'
import { FC } from 'react'

export const HeaderLink: FC<LinkProps> = ({ children, ...props }) => {
  return (
    /* ↓Type error: Expression produces a union type that is too complex to represent. */
    <Link as={NextLink} {...props}>
      {children}
    </Link>
  )
}
r4air4ai

このことについて話し合われてるスレッド

https://github.com/pmndrs/drei/issues/704
https://github.com/pmndrs/drei/issues/823
https://github.com/pmndrs/drei/issues/1193

https://stackoverflow.com/questions/68692230/ts-expression-produces-a-union-type-that-is-too-complex-to-represent-with-materi

まとめ

なんか修正するには多大の労力がかかるらしい。ということで、すぐに修正されるような問題ではないっぽい。

We can try writing into ThreeElements in a major, but I think this would need a significant refactor to narrow everything on top of pending types work (related #823, #1075).
https://github.com/pmndrs/drei/issues/1193#issuecomment-1363320267

r4air4ai

解決案

問題は TypeScript にあって、three.js の複雑すぎる型が問題っぽいので、とりあえず as any を使って型チェックさせなければいいのでは。知らんけど。

r4air4ai

解決策

先ほどのコードで、Linkコンポーネントへ渡す props の型を any にしてみる。HeaderLink関数の引数ではちゃんと型を指定しておけば、ちゃんと補完も効くし実用上問題ないはず(多分)。

import { Link, LinkProps } from '@chakra-ui/react'
import NextLink from 'next/link'
import { FC } from 'react'

export const HeaderLink: FC<LinkProps> = ({ children, ...props }) => {
  const propsAny = props as any
  return (
    <Link as={NextLink} {...propsAny}>
      {children}
    </Link>
  )
}

なんか as any って禁断の魔術感があってあまり使いたくはないが、一応これでビルドエラーは消えた。あんまり良い方法ではなさそうなので、もっといいやり方を知っている方がいればご教授願いたい。

このスクラップは2022/12/30にクローズされました