๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿชฒ debug

[ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ] Type error: Re-exporting a type when 'isolatedModules' is enabled requires using 'export type'.

2025.03.12 - [๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป dev] - ๐Ÿฌ React import ์‹œ Wrapper ํŒจํ„ด ํ™œ์šฉํ•ด ๋ณด๊ธฐ

 

๐Ÿฌ React import ์‹œ Wrapper ํŒจํ„ด ํ™œ์šฉํ•ด๋ณด๊ธฐ

์ตœ๊ทผ์— ๋ฆฌ์•กํŠธ์—์„œ import ์‹œ์— wrapper ํŒจํ„ด์„ ํ™œ์šฉํ–ˆ๋‹ค๋Š” ๊ธ€์„ ์ฝ์—ˆ๋‹ค.lodash๋‚˜ Framer Motion๋ฅผ ์ „์ฒด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‹จ์œ„๋กœ importํ•˜๋Š” ์ƒํ™ฉ์ด ์ข…์ข… ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.์˜ˆ๋ฅผ ๋“ค์–ด, lodash๋ฅผ > ๊ณผ ๊ฐ™์ด importํ•˜๋Š” ๊ฒฝ์šฐ

pyotato-dev.tistory.com

 

 

์ด์ „ import ์‹œ wrapper ํŒจํ„ด์„ ํ™œ์šฉํ•ด์„œ ๋ดค๋‹ค.

๊ทผ๋ฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

// Type error: Re-exporting a type when 'isolatedModules' is enabled requires using 'export type'.
export { classNames, Motion, MotionProps };

 

์ด์ „ MotionProps๋ฅผ ์‚ดํŽด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

import { AnimationProps, motion, MotionStyle, SVGMotionProps, Variant, Variants } from 'framer-motion';

// ์ค‘๋žต

export interface MotionProps {
  variants: Variants;
  animationProps: AnimationProps;
  motionStyle: MotionStyle;
  svgProps: SVGMotionProps<SVGPathElement>;
}

๐Ÿ”Ž ๋ฌธ์ œ ์›์ธ ํƒ์ƒ‰

"isolatedModules"๋ฅผ ํ”„๋กœ์ ํŠธ์—์„œ ์ฐพ์•„๋ณด๋‹ˆ, ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์œผ๋กœ true๋ฅผ ์„ค์ •ํ•˜๋ฉด, ๋ชจํ˜ธํ•œ ๊ฐ’/ํƒ€์ž…์„ importํ•  ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ ๋‚ธ๋‹ค. (isolateModules ์„ค์ • ์ด์œ ์™€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚˜์ค‘์— ๋‹ค๋ค„๋ณด๊ณ ์ž ํ•œ๋‹ค.)

 

isolatedModules๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ 3.8 ์ดํ›„์—๋Š” type-only import๊ณผ export ์ƒˆ๋กœ์šด ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด import type์€ ํƒ€์ž… annotation๊ณผ declaration๋กœ ์“ฐ์ผ declaration๋งŒ importํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰, ๋Ÿฐํƒ€์ž„ ์‹œ์—๋Š” ์™„์ „ํžˆ ์ œ๊ฑฐ๊ฐ€ ๋˜์–ด ํ”์ ์ด ์—†์–ด์ง„๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ export type์€ ํƒ€์ž… ์ฝ˜ํ…์ŠคํŠธ์—๋งŒ ์“ฐ์ผ export๋งŒ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ output์— ์™„์ „ํžˆ ์ œ๊ฑฐ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

import type { SomeThing } from "./some-module.js";
export type { SomeThing };

 

์ค‘์š”ํ•œ ๊ฒƒ์€ ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ ๋Ÿฐํƒ€์ž„์— ๊ฐ’์ด ์žˆ๊ณ , ๋””์ž์ธ ํƒ€์ž„์— ํƒ€์ž…์ด ์žˆ๊ณ , ์ฝ˜ํ…์ŠคํŠธ์— ๋”ฐ๋ผ ์“ฐ์ž„์ด ๋‹ฌ๋ผ์ง„๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

import type์„ ํ™œ์šฉํ•ด ํด๋ž˜์Šค๋ฅผ import๋ฅผ ํ•  ๊ฒฝ์šฐ, extend๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

import type { Component } from "react";
interface ButtonProps {
  // ...
}
class Button extends Component<ButtonProps> {
  //               ~~~~~~~~~
  // error! 'Component' only refers to a type, but is being used as a value here.
  // โš ๏ธ(Component)๋Š” ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚ค์ง€๋งŒ ๊ฐ’์œผ๋กœ ์“ฐ์ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  // ...
}

 

 

Flow๋ฅผ ์‚ฌ์šฉํ•ด ๋ณธ ๊ฒฝํ—˜์ด ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ๋ฌธ๋ฒ•์ด ์ต์ˆ™ํ•  ๊ฒƒ์ด๋‹ค.

๋‹ค๋งŒ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ฐจ์ด์  ์ค‘ ํ•˜๋‚˜๋Š” ๋ชจํ˜ธํ•จ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์ œ์•ฝ์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋Š” ์ ์ด๋‹ค.

// Is only 'Foo' a type? Or every declaration in the import?
// We just give an error because it's not clear.
import type Foo, { Bar, Baz } from "some-module";
//     ~~~~~~~~~~~~~~~~~~~~~~
// error! A type-only import can specify a default import or named bindings, but not both.

 

 import type๊ณผ ํ•จ๊ป˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ 3.8๋Š” ๋Ÿฐํƒ€์ž„์— ์“ฐ์ด์ง€ ์•Š์„ import๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€์ ์œผ๋กœ ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ž˜๊ทธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค : importsNotUsedAsValues

  • ํ•ด๋‹น ํ”Œ๋ž˜๊ทธ ๊ฐ’์€ 3๊ฐœ ์ค‘ ํ•˜๋‚˜๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•˜๋‹ค:
    • remove : ์˜ค๋Š˜๋‚  import ์˜ ๊ธฐ๋ณธ ๋™์ž‘ ๋ฐฉ์‹
    • preserve: ๊ฐ’์ด ์“ฐ์ด์ง€ ์•Š๋Š” Import ๋ชจ๋‘ ์œ ์ง€. import/side-effect๊ฐ€ ์œ ์ง€๋˜๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ๋‹ค.
    • error: preserve์™€ ๊ฐ™์€ ์˜ต์…˜์ด์ง€๋งŒ value import๊ฐ€ ํƒ€์ž…์œผ๋กœ ์“ฐ์ผ ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ ๋‚ธ๋‹ค. ์‹ค์ˆ˜๋กœ ๊ฐ’์ด import๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋ฉด์„œ side-effect import๊ฐ€ explicitํ•˜๋„๋ก ์“ฐ์ผ ์ˆ˜ ์žˆ๋‹ค.

๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ข…ํ•ฉํ•ด ๋ณด๋‹ˆ MotionProps๋Š” ํƒ€์ž…์œผ๋กœ ์“ฐ๊ณ  isolatedModules๋ฅผ true๋ผ๊ณ  ์„ค์ •ํ•ด ๋‘” ์ƒํ™ฉ์—์„œ,

๋””ํดํŠธ๋กœ ํƒ€์ž…์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ์ œ๊ฑฐํ•ด ๋ฒ„๋ฆฌ๋ฏ€๋กœ ๋‹ค์‹œ exportํ•˜๋Š”๋ฐ ๊ฐ’์œผ๋กœ exportํ•˜๋ ค๋Š” ๋ถˆ์ผ์น˜ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๊ฑฐ ๊ฐ™๋‹ค.

๐Ÿ˜Š Solution

ํƒ€์ž…์œผ๋กœ ์“ฐ์ผ MotionProps์— ํ•ด๋‹น ์ •๋ณด๋ฅผ type ํ‚ค์›Œ๋“œ๋กœ ๋ช…์‹œํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.

export { classNames, Motion, MotionProps }; //before
export { classNames, Motion, type MotionProps }; //after

 


References

 

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export

 

Documentation - TypeScript 3.8

TypeScript 3.8 Release Notes

www.typescriptlang.org

https://stackoverflow.com/questions/70416680/re-exporting-a-type-when-the-isolatedmodules-flag-is-provided-requires-using

 

Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.ts

I have created multiple interfaces and want to ship them all from a common index.ts file as shown below: --pages ------index.interface.ts --index.ts Now In my index.ts I am exporting something like:

stackoverflow.com