Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define plain declaration file without including any other types #338

Open
doteric opened this issue Nov 21, 2024 · 3 comments
Open

Define plain declaration file without including any other types #338

doteric opened this issue Nov 21, 2024 · 3 comments

Comments

@doteric
Copy link

doteric commented Nov 21, 2024

Hello 👋

I'm wondering if I could achieve a generated declaration file containing only the complied types of the exported types using this package.
For example I have the following as input:

// Just an example
import type { ResponseBodyType as ResultResponseBodyType } from '../result/index.js';
import type { BodyType as ResultBodyType } from '../result/modules/eventParser.js';

export type ResultReqBodyType = ResultBodyType;
export type ResultResBodyType = ResultResponseBodyType;


// OR (other example not used in examples below)
export type { ResponseBodyType as ResultResBodyType } from '../result/index.js';
export type { BodyType as ResultReqBodyType } from '../result/modules/eventParser.js';

And would like to achieve the following output (more or less):

export type ResultReqBodyType = { accountNumber?: string };

export type ResultResBodyType =
  | { issues: string[]; message?: undefined; result?: undefined }
  | { message: string; issues?: undefined; result?: undefined }
  | { result: any; issues?: undefined; message?: undefined };

But instead get the following (as an example):

// Generated by dts-bundle-generator v9.5.1

import { APIGatewayProxyEvent } from 'aws-lambda';
import { z } from 'zod';

declare const main: (event: APIGatewayProxyEvent) => Promise<{
	statusCode: number;
	body: {
		issues: string[];
		message?: undefined;
		result?: undefined;
	};
} | {
	statusCode: number;
	body: {
		message: string;
		issues?: undefined;
		result?: undefined;
	};
} | {
	body: {
		result: any;
		issues?: undefined;
		message?: undefined;
	};
	statusCode?: undefined;
}>;
type ResponseBodyType = Awaited<ReturnType<typeof main>>["body"];
declare const handlerBodyZod: z.ZodObject<{
	accountNumber: z.ZodString;
}, "strip", z.ZodTypeAny, {
	accountNumber: string;
}, {
	accountNumber: string;
}>;
type BodyType = z.infer<typeof handlerBodyZod>;
export type ResultReqBodyType = BodyType;
export type ResultResBodyType = ResponseBodyType;

export {};

Currently I've coded my own simple implementation to achieve the desired output, but I'm wondering if this package could do exactly that, so that I wouldn't have to maintain the approach I've coded as it lacks some features.

Cheers 🎉

@doteric
Copy link
Author

doteric commented Dec 5, 2024

@timocov , any time to take a look on this by any chance? 🙏

Edit: I went back to check the file config that I previously did not notice and I found inlineDeclareExternals which works and now I get

// Generated by dts-bundle-generator v9.5.1

declare const main: (event: APIGatewayProxyEvent) => Promise<{
	statusCode: number;
	body: {
		issues: import("zod").ZodIssue[]; // Still wrong, it should be using `ZodIssue[]` inlined and not import `zod`!
		message?: undefined;
		result?: undefined;
	};
} | {
	statusCode: number;
	body: {
		message: string;
		issues?: undefined;
		result?: undefined;
	};
} | {
	body: {
		result: {};
		issues?: undefined;
		message?: undefined;
	};
	statusCode?: undefined;
}>;
type ResponseBodyType = Awaited<ReturnType<typeof main>>["body"];
declare const handlerBodyZod: z.ZodObject<{
	accountNumber: z.ZodString;
}, "strip", z.ZodTypeAny, {
	accountNumber: string;
}, {
	accountNumber: string;
}>;
type BodyType = z.infer<typeof handlerBodyZod>;

export {
	BodyType as ResultReqBodyType,
	ResponseBodyType as ResultResBodyType,
};

export as namespace MyModuleName;

export {};

Which is decent progress, but still not it.
First of all zod is still being imported (also z.xxx not resolved correctly) and also, would it be possible to inline all the types to just have the ones that I am exporting as inline?
So something more or less like this:

export type ResultReqBodyType = { accountNumber?: string };

export type ResultResBodyType =
  | { issues: string[]; message?: undefined; result?: undefined }
  | { message: string; issues?: undefined; result?: undefined }
  | { result: any; issues?: undefined; message?: undefined };

Btw. Don't look directly at the ResultResBodyType type itself as it's not fully correct yet.


Also, when an .ejs file is imported the generator seems to fail as a whole. Error:

src/example.ts(4,26): error TS2307: Cannot find module './example.ejs' or its corresponding type declarations.

example.ts:

import { renderFile } from 'ejs';

import type { BodyType } from './eventParser.js';
import htmlBodyPath from './emailContent.ejs';

const example = async (
  body: BodyType & { submitter: string }
): Promise<string> =>
  new Promise((resolve, reject) => {
    return renderFile(htmlBodyPath, body, (err, renderedHtml) => {
      if (err) {
        reject(err);
      }
      resolve(renderedHtml);
    });
  });

export default example;

@timocov
Copy link
Owner

timocov commented Dec 5, 2024

the complied types of the exported types using this package

So you want to "compute" types (not what they reference but actual type at the complication time)?

Still wrong, it should be using ZodIssue[] inlined and not import zod!

Adding zod to --external-inlines should help. But it might be dangerous for users of your library - if they have zod installed and they would want to pass you an object that is marked as from their zod library to yours, they might get incompatibility compilation error, so be careful with it.

Also, when an .ejs file is imported the generator seems to fail as a whole. Error:

Please file another issue and provide a repro there so I can take a look.

@doteric
Copy link
Author

doteric commented Dec 6, 2024

So you want to "compute" types (not what they reference but actual type at the complication time)?

If I understand you correctly, then yes, exactly 😄 . I'd like to have a clean file generated with just the compiled types of ResultResBodyType and ResultReqBodyType (for example) and using dts-bundle-generator currently results in a pretty big file, especially when I add zod to inlinedLibraries.

Adding zod to --external-inlines should help. But it might be dangerous for users of your library - if they have zod installed and they would want to pass you an object that is marked as from their zod library to yours, they might get incompatibility compilation error, so be careful with it.

Adding zod to inlinedLibraries actually worked, but still it's not ideal due to how much is generated now. As for the mentioned problem, this is not a problem for us at all, because these typings will be just used on frontend for request/response body typing.

Please file another issue and provide a repro there so I can take a look.

Sure, here it is #340

Big thanks @timocov btw 🙇 Really appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants