pino icon indicating copy to clipboard operation
pino copied to clipboard

Improve generics for Logger, LoggerOptions, LogFn and WriteFn

Open emilio-toledo opened this issue 7 months ago • 0 comments

Use Case

Hello, I am a type obsessive person and currently the only way that I found to strictly type everything in Pino is with something like what I am currently using:

import CustomToast from "$lib/components/CustomToast.svelte";
import type { Error as Err } from "@repo/models";
import { pino, type Logger, type LoggerOptions } from "pino";
import toast from "svelte-french-toast";

type CustomLogger<CustomLevels extends string = never> = Omit<
	Logger<CustomLevels>,
	InfoLogLevel | ErrorLogLevel
> &
	(InfoLogLevelFunctions & ErrorLogLevelFunctions);

type CustomLoggerOptions = Omit<
	NonNullable<LoggerOptions<CustomLevels>>,
	"browser" | "customLevels"
> & {
	browser?: Omit<NonNullable<LoggerOptions["browser"]>, "write"> & {
		write?:
			| CustomLogFn
			| Partial<InfoLogLevelFunctions>
			| Partial<ErrorLogLevelFunctions>;
	};
	customLevels: {
		[K in CustomLevels]: number;
	};
};

type CustomLevels = "success";

type ErrorLogLevel = "fatal" | "error";
type InfoLogLevel =
	| "warn"
	| "info"
	| "debug"
	| "trace"
	| "silent"
	| CustomLevels;

type InfoLogLevelFunctions = {
	[K in InfoLogLevel]: CustomLogFn;
};

type ErrorLogLevelFunctions = {
	[K in ErrorLogLevel]: CustomErrorFn;
};

type CustomLogFn = (data: {
	name: string;
	message: string;
}) => void;

type CustomErrorFn = (data: Err) => void;

const options: CustomLoggerOptions = {
	browser: {
		write: {
			error: (args) => {
				toast(CustomToast, {
					duration: 5000,
					position: "bottom-right",

					//@ts-ignore
					props: {
						type: "error",
						title: "Failed",
						id: args.id,
						description: args.message,
					},
				});

				console.log(args);
			},

			info: (args) => {
				toast(CustomToast, {
					duration: 5000,
					position: "bottom-right",

					//@ts-ignore
					props: {
						type: "info",
						title: args.name,
						description: args.message,
					},
				});

				console.log(args);
			},
		},
	},
	customLevels: {
		success: 20,
	},
};

export const logger: CustomLogger<CustomLevels> = pino(
	options as LoggerOptions<CustomLevels>,
);

Is it possible to have some generics for these types outside of the individual logger.method<type>()?

emilio-toledo avatar Jul 19 '24 08:07 emilio-toledo