Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions packages/svelte2tsx/src/emitDts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ function loadTsconfig(config: EmitDtsConfig, svelteMap: SvelteMap) {
options: {
...options,
noEmit: false, // Set to true in case of jsconfig, force false, else nothing is emitted
moduleResolution:
// NodeJS: up to 4.9, Node10: since 5.0
(ts.ModuleResolutionKind as any).NodeJs ?? ts.ModuleResolutionKind.Node10, // Classic if not set, which gives wrong results
moduleResolution: ts.ModuleResolutionKind.Node16,
declaration: true, // Needed for d.ts file generation
emitDeclarationOnly: true, // We only want d.ts file generation
declarationDir: config.declarationDir, // Where to put the declarations
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Cross-Package Generic Types Test

This test validates that generic type information is correctly preserved when importing generic classes from external packages during `.d.ts` generation.

## Issue
Before the fix, when using modern module resolution (bundler/node16), cross-package imports of generic classes would lose their type information and fall back to `any` in generated declaration files.

## Test Structure
- `core-package/` - Mock external package containing `GenericToken<T>` class
- `src/consumer.ts` - Consumes the generic class with type parameters
- `expected/` - Expected output showing preserved generic types

## Key Test Case
```typescript
// This should preserve the generic type as GenericToken<MyService>
// Before the fix: compiled as 'any' due to module resolution issues
// After the fix: correctly typed as GenericToken<MyService>
export const SERVICE_TOKEN = new GenericToken<MyService>('MyService');
```

## Fix
Updated `emitDts.ts` to use modern module resolution (bundler/node16) instead of legacy node10 resolution.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@test/core",
"version": "1.0.0",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { GenericToken } from '@test/core';
export declare class MyService {
private name;
constructor(name: string);
getName(): string;
}
export declare const SERVICE_TOKEN: GenericToken<MyService>;
export declare const ANNOTATED_TOKEN: GenericToken<MyService>;
export declare const ASSERTION_TOKEN: GenericToken<MyService>;
export declare class AnotherService {
value: number;
}
export declare const ANOTHER_TOKEN: GenericToken<AnotherService>;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './consumer.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "test-cross-package-generics",
"version": "0.0.1",
"type": "module",
"dependencies": {
"@test/core": "1.0.0"
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GenericToken } from '@test/core';

export class MyService {
constructor(private name: string) {}
getName() { return this.name; }
}

// This should preserve the generic type as GenericToken<MyService>
// Before the fix, this would be compiled as 'any' due to module resolution issues
export const SERVICE_TOKEN = new GenericToken<MyService>('MyService');

// These explicit annotations should work regardless
export const ANNOTATED_TOKEN: GenericToken<MyService> = new GenericToken<MyService>('MyService');
export const ASSERTION_TOKEN = new GenericToken<MyService>('MyService') as GenericToken<MyService>;

// Test with different generic types
export class AnotherService {
value = 42;
}

export const ANOTHER_TOKEN = new GenericToken<AnotherService>('AnotherService');

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './consumer.js';

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM"],
"module": "ESNext",
"declaration": true,
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"]
}