How to fix Default export of the module has or is using private name 'X' in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 8, 2025· 193 views

This TypeScript error occurs when generating declaration files (.d.ts) for code that exports a type or interface that hasn't been explicitly exported from the module. The compiler cannot create valid type declarations when the default export references private (unexported) types.

Quick fix

Fixes TS4082

// BEFORE - Causes TS4082 error
interface Props {
  name: string;
  age: number;
}

export default defineComponent({
  props: defineProps<Props>()
});

// AFTER - Fixed by exporting Props
export interface Props {
  name: string;
  age: number;
}

export default defineComponent({
  props: defineProps<Props>()
});
  1. Export the referenced type or interface
  2. Use inline type definitions
  3. Disable declaration file generation for specific files
  4. Add explicit type annotations to hide private types
typescript — error
// BEFORE - Causes TS4082 error
interface Props {
name: string;
age: number;
}
export default defineComponent({
props: defineProps<Props>()
});
// AFTER - Fixed by exporting Props
export interface Props {
name: string;
age: number;
}
export default defineComponent({
props: defineProps<Props>()
});
Default export of the module has or is using private name 'X'

What this error means

The "Default export of the module has or is using private name" error (TS4082) appears when TypeScript's declaration file generator encounters a default export that references a type, interface, or class that is not publicly exported from the module. This happens specifically when you have declaration file generation enabled (via "declaration": true in tsconfig.json). TypeScript's declaration emitter needs to serialize all types used in public exports into .d.ts files that other developers can use. When it encounters a private type in an export signature, it cannot safely emit that type because: 1. The type isn't imported/exported in the declaration file 2. Adding automatic imports would expose implementation details the developer didn't intend to make public 3. The resulting declaration file would be invalid or incomplete This error is particularly common in: - Vue components using `defineProps<Props>()` where Props isn't exported - Default exports of functions/classes that use internal types in their signatures - Libraries attempting to export functionality that depends on private types - Projects using frameworks that generate type definitions at build time

Typical symptoms

  • Build fails with error code TS4082 when generating declaration files
  • Error message mentions 'has or is using private name' followed by a type name
  • Compilation succeeds when 'declaration' is set to false in tsconfig.json
  • IDE shows error on default export statement
  • Error appears when building a library or package for distribution
  • Issue occurs in Vue components with defineProps using unexported interface
  • Rollup or webpack builds fail during type generation phase

Common causes

  1. Interface or type used in default export is not explicitly exported from the module
  2. Class or function signature references a private type as parameter or return value
  3. Vue component uses defineProps with an unexported Props interface
  4. Default export references types from dependencies without re-exporting them
  5. Declaration file generation is enabled but internal types are exposed in public API
  6. Third-party library type definitions contain private type references
  7. Build configuration includes test or story files in type declaration generation

How to fix "Default export of the module has or is using private name 'X'"

1Export the referenced type or interface

The most straightforward fix is to explicitly export the type that's being referenced:

typescript
// BEFORE - Causes TS4082 error
interface Props {
  name: string;
  age: number;
}

export default defineComponent({
  props: defineProps<Props>()
});

// AFTER - Fixed by exporting Props
export interface Props {
  name: string;
  age: number;
}

export default defineComponent({
  props: defineProps<Props>()
});

For React components:

typescript
// BEFORE - Error when building library
interface ButtonProps {
  variant: 'primary' | 'secondary';
  onClick: () => void;
}

export default function Button(props: ButtonProps) {
  return <button onClick={props.onClick}>{props.children}</button>;
}

// AFTER - Fixed
export interface ButtonProps {
  variant: 'primary' | 'secondary';
  onClick: () => void;
}

export default function Button(props: ButtonProps) {
  return <button onClick={props.onClick}>{props.children}</button>;
}

This makes the type part of your public API, allowing TypeScript to include it in generated declarations.

2Use inline type definitions

If you don't want to export the type, define it inline directly in the export:

typescript
// Instead of a separate interface
interface Props {
  title: string;
  count: number;
}
export default defineProps<Props>();

// Use inline type definition
export default defineProps<{
  title: string;
  count: number;
}>();

For function exports:

typescript
// BEFORE - Private Config type
interface Config {
  apiKey: string;
  timeout: number;
}

export default function initialize(config: Config) {
  // ...
}

// AFTER - Inline type
export default function initialize(config: {
  apiKey: string;
  timeout: number;
}) {
  // ...
}

This approach keeps your module's public API simple while avoiding the private name error.

3Disable declaration file generation for specific files

If certain files shouldn't produce type declarations (like tests, stories, or examples), exclude them:

Update tsconfig.json:

json
{
  "compilerOptions": {
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules",
    "**/*.test.ts",
    "**/*.spec.ts",
    "**/*.stories.ts",
    "**/__tests__/**"
  ]
}

For build tools like Rollup with @rollup/plugin-typescript:

javascript
// rollup.config.js
import typescript from '@rollup/plugin-typescript';

export default {
  plugins: [
    typescript({
      exclude: [
        '**/*.test.ts',
        '**/*.spec.ts',
        '**/*.stories.tsx',
        'src/__tests__/**'
      ]
    })
  ]
};

This prevents TypeScript from trying to generate declarations for files that might use private types liberally.

4Add explicit type annotations to hide private types

Use explicit type annotations to mask the private type from the declaration emitter:

typescript
// BEFORE - Private Test class leaks into export
class Test {
  constructor(private value: string) {}
}

export const instance = new Test("value");
// Error: Exported variable 'instance' has or is using private name 'Test'

// AFTER - Explicit 'any' type annotation
export const instance: any = new Test("value");

// BETTER - Define a public interface
export interface Instance {
  getValue(): string;
}

class Test implements Instance {
  constructor(private value: string) {}
  getValue() { return this.value; }
}

export const instance: Instance = new Test("value");

For functions with complex return types:

typescript
// Private internal type
type InternalResult = {
  _internal: string;
  data: string;
};

// Hide implementation details with explicit return type
export default function process(): { data: string } {
  const result: InternalResult = {
    _internal: "secret",
    data: "public"
  };
  return result;
}
5Use named exports instead of default exports

Converting to named exports can sometimes avoid the issue and is generally considered best practice:

typescript
// BEFORE - Default export with private type
interface ComponentProps {
  title: string;
}

export default function Component(props: ComponentProps) {
  return <div>{props.title}</div>;
}

// AFTER - Named exports (recommended)
export interface ComponentProps {
  title: string;
}

export function Component(props: ComponentProps) {
  return <div>{props.title}</div>;
}

Named exports are easier for tree-shaking, refactoring, and avoiding this specific error class. They also make the module's public API more explicit.

Usage changes from:

typescript
import Component from './Component';

To:

typescript
import { Component } from './Component';
6Temporarily disable declaration generation (debugging only)

As a last resort for debugging, disable declaration file generation to verify this is the issue:

json
// tsconfig.json
{
  "compilerOptions": {
    "declaration": false,
    // Or temporarily:
    // "declaration": true,
    // "declarationMap": false
  }
}

Warning: This is not a proper fix if you're building a library that others will consume. Declaration files are essential for TypeScript library users to get type checking and autocomplete.

Use this approach only to:
- Confirm the error is related to declaration generation
- Unblock development while planning proper fix
- Build applications (not libraries) where .d.ts files aren't distributed

Advanced notes

### Understanding Declaration File Generation

TypeScript's declaration emitter follows strict rules to ensure generated .d.ts files are valid:

1. No implementation details: Declaration files should only contain type information, not runtime code
2. All referenced types must be resolvable: Any type appearing in a declaration must be importable by consumers
3. Private types cannot be serialized: The emitter won't automatically export types you didn't intend to share

When you write:

typescript
interface InternalConfig {
  secret: string;
}

export default function init(config: InternalConfig) {
  // ...
}

The emitter tries to generate:

typescript
// Would be invalid - InternalConfig is not exported!
export default function init(config: InternalConfig): void;

This creates an invalid declaration file because InternalConfig isn't defined or imported.

### Vue-Specific Considerations

Vue 3's defineProps<T>() is a compile-time macro that extracts type information. When used with private types:

typescript
// Problematic pattern
interface Props {
  msg: string;
}

export default defineComponent({
  setup() {
    const props = defineProps<Props>();
  }
});

Solutions for Vue:

1. Export the Props interface:

typescript
export interface Props {
  msg: string;
}

2. Use inline types:

typescript
const props = defineProps<{
  msg: string;
}>();

3. Use runtime props definition (loses some type safety):

typescript
const props = defineProps({
  msg: { type: String, required: true }
});

### Library Development Best Practices

When building TypeScript libraries:

1. Design your public API intentionally: Decide which types should be exported
2. Use index.ts barrel exports: Explicitly control what's public:

typescript
// src/index.ts
export { Button, type ButtonProps } from './Button';
export { Input, type InputProps } from './Input';
// Don't export internal utilities

3. Consider API extractors: Tools like [@microsoft/api-extractor](https://api-extractor.com/) can help manage declaration files and detect private type leaks

4. Document exported types: If a type is exported for declaration file purposes, document whether it's meant for external use

### Third-Party Type Issues

Sometimes the error comes from dependencies:

typescript
// Your code
import { SomeFunction } from 'third-party-lib';

export default SomeFunction;
// Error: Default export uses private name from 'third-party-lib'

Fixes:

1. Update the dependency - may be fixed in newer version
2. Report the issue to the library maintainer
3. Create a wrapper with explicit types:

typescript
import { SomeFunction } from 'third-party-lib';

export default function wrapped(...args: any[]): any {
  return SomeFunction(...args);
}

### Composite Projects and Project References

In monorepos using TypeScript project references, ensure referenced projects have proper exports:

json
// packages/shared/tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true
  }
}
typescript
// packages/shared/src/index.ts
// Export all types that dependent packages might need
export interface Config { ... }
export type Status = 'active' | 'inactive';

### Debugging Declaration Output

To see what TypeScript is trying to generate:

bash
# Generate declarations and inspect output
npx tsc --declaration --emitDeclarationOnly --outDir dist-types

# Review the generated .d.ts files
cat dist-types/yourfile.d.ts

This shows exactly what the emitter is struggling with.

Frequently asked questions

What does "TS4082" mean?
The "Default export of the module has or is using private name" error (TS4082) appears when TypeScript's declaration file generator encounters a default export that references a type, interface, or class that is not publicly exported from the module. json). ts files that other developers can use.
How do I fix "TS4082"?
This TypeScript error occurs when generating declaration files (.d.ts) for code that exports a type or interface that hasn't been explicitly exported from the module. The compiler cannot create valid type declarations when the default export references private (unexported) types.
What causes "TS4082"?
Interface or type used in default export is not explicitly exported from the module Class or function signature references a private type as parameter or return value Vue component uses defineProps with an unexported Props interface
Is the "TS4082" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading