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

fix: make types stricter #1843

Merged
merged 2 commits into from
Nov 15, 2023
Merged
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
50 changes: 25 additions & 25 deletions pino.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ type TimeFn = () => string;
type MixinFn = (mergeObject: object, level: number) => object;
type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object;

type CustomLevelLogger<Options> = Options extends { customLevels: Record<string, number> } ? Record<keyof Options["customLevels"], LogFn> : Record<never, LogFn>
type CustomLevelLogger<CustomLevels extends Record<string, number>> = Record<keyof CustomLevels, LogFn>

/**
* A synchronous callback that will run on each creation of a new child.
* @param child: The newly created child logger instance.
*/
type OnChildCallback<Options = LoggerOptions> = <ChildOptions extends pino.ChildLoggerOptions>(child: pino.Logger<Options & ChildOptions>) => void
type OnChildCallback<CustomLevels extends Record<string, number> = {}> = (child: pino.Logger<CustomLevels>) => void

interface redactOptions {
paths: string[];
censor?: string | ((value: any, path: string[]) => any);
remove?: boolean;
}

export interface LoggerExtras<Options = LoggerOptions> extends EventEmitter {
export interface LoggerExtras<CustomLevels extends Record<string, number> = {}> extends EventEmitter {
/**
* Exposes the Pino package version. Also available on the exported pino function.
*/
Expand All @@ -60,7 +60,7 @@ export interface LoggerExtras<Options = LoggerOptions> extends EventEmitter {
/**
* Define additional logging levels.
*/
customLevels: { [key: string]: number };
customLevels: CustomLevels;
/**
* Use only defined `customLevels` and omit Pino's levels.
*/
Expand All @@ -80,12 +80,12 @@ export interface LoggerExtras<Options = LoggerOptions> extends EventEmitter {
* @param options: an options object that will override child logger inherited options.
* @returns a child logger instance.
*/
child<ChildOptions extends pino.ChildLoggerOptions = {}>(bindings: pino.Bindings, options?: ChildOptions): pino.Logger<Options & ChildOptions>;
child<ChildCustomLevels extends Record<string, number> = {}>(bindings: pino.Bindings, options?: ChildLoggerOptions<ChildCustomLevels>): pino.Logger<CustomLevels & ChildCustomLevels>;

/**
* This can be used to modify the callback function on creation of a new child.
*/
onChild: OnChildCallback<Options>;
onChild: OnChildCallback<CustomLevels>;

/**
* Registers a listener function that is triggered when the level is changed.
Expand All @@ -95,12 +95,12 @@ export interface LoggerExtras<Options = LoggerOptions> extends EventEmitter {
* @param event: only ever fires the `'level-change'` event
* @param listener: The listener is passed four arguments: `levelLabel`, `levelValue`, `previousLevelLabel`, `previousLevelValue`.
*/
on<Opts = Options>(event: "level-change", listener: pino.LevelChangeEventListener<Opts>): this;
addListener<Opts = Options>(event: "level-change", listener: pino.LevelChangeEventListener<Opts>): this;
once<Opts = Options>(event: "level-change", listener: pino.LevelChangeEventListener<Opts>): this;
prependListener<Opts = Options>(event: "level-change", listener: pino.LevelChangeEventListener<Opts>): this;
prependOnceListener<Opts = Options>(event: "level-change", listener: pino.LevelChangeEventListener<Opts>): this;
removeListener<Opts = Options>(event: "level-change", listener: pino.LevelChangeEventListener<Opts>): this;
on(event: "level-change", listener: pino.LevelChangeEventListener<CustomLevels>): this;
addListener(event: "level-change", listener: pino.LevelChangeEventListener<CustomLevels>): this;
once(event: "level-change", listener: pino.LevelChangeEventListener<CustomLevels>): this;
prependListener(event: "level-change", listener: pino.LevelChangeEventListener<CustomLevels>): this;
prependOnceListener(event: "level-change", listener: pino.LevelChangeEventListener<CustomLevels>): this;
removeListener(event: "level-change", listener: pino.LevelChangeEventListener<CustomLevels>): this;

/**
* A utility method for determining if a given log level will write to the destination.
Expand Down Expand Up @@ -225,17 +225,17 @@ declare namespace pino {
type SerializerFn = (value: any) => any;
type WriteFn = (o: object) => void;

type LevelChangeEventListener<Options = LoggerOptions> = (
type LevelChangeEventListener<CustomLevels extends Record<string, number> = {}> = (
lvl: LevelWithSilentOrString,
val: number,
prevLvl: LevelWithSilentOrString,
prevVal: number,
logger: Logger<Options>
logger: Logger<CustomLevels>
) => void;

type LogDescriptor = Record<string, any>;

type Logger<Options = LoggerOptions> = BaseLogger & LoggerExtras<Options> & CustomLevelLogger<Options>;
type Logger<CustomLevels extends Record<string, number> = {}> = BaseLogger & LoggerExtras<CustomLevels> & CustomLevelLogger<CustomLevels>;

type SerializedError = pinoStdSerializers.SerializedError;
type SerializedResponse = pinoStdSerializers.SerializedResponse;
Expand Down Expand Up @@ -320,7 +320,7 @@ declare namespace pino {
(msg: string, ...args: any[]): void;
}

interface LoggerOptions {
interface LoggerOptions<CustomLevels extends Record<string, number>> {
transport?: TransportSingleOptions | TransportMultiOptions | TransportPipelineOptions
/**
* Avoid error causes by circular references in the object tree. Default: `true`.
Expand Down Expand Up @@ -353,7 +353,7 @@ declare namespace pino {
* Use this option to define additional logging levels.
* The keys of the object correspond the namespace of the log level, and the values should be the numerical value of the level.
*/
customLevels?: { [key: string]: number };
customLevels?: CustomLevels;
/**
* Use this option to only use defined `customLevels` and omit Pino's levels.
* Logger's default `level` must be changed to a value in `customLevels` in order to use `useOnlyCustomLevels`
Expand Down Expand Up @@ -638,10 +638,10 @@ declare namespace pino {
crlf?: boolean;
}

interface ChildLoggerOptions {
interface ChildLoggerOptions<CustomLevels extends Record<string, number>> {
level?: LevelOrString;
serializers?: { [key: string]: SerializerFn };
customLevels?: { [key: string]: number };
customLevels?: CustomLevels;
formatters?: {
level?: (label: string, number: number) => object;
bindings?: (bindings: Bindings) => object;
Expand Down Expand Up @@ -791,15 +791,15 @@ declare namespace pino {
* relative protocol is enabled. Default: process.stdout
* @returns a new logger instance.
*/
declare function pino<Options extends LoggerOptions | DestinationStream>(optionsOrStream?: Options): Logger<Options>;
declare function pino<CustomLevels extends { [key: string]: number; } = {}>(optionsOrStream?: LoggerOptions<CustomLevels> | DestinationStream): Logger<CustomLevels>;

/**
* @param [options]: an options object
* @param [stream]: a writable stream where the logs will be written. It can also receive some log-line metadata, if the
* relative protocol is enabled. Default: process.stdout
* @returns a new logger instance.
*/
declare function pino<Options extends LoggerOptions>(options: Options, stream: DestinationStream): Logger<Options>;
declare function pino<CustomLevels extends { [key: string]: number; }>(options: LoggerOptions<CustomLevels>, stream: DestinationStream): Logger<CustomLevels>;


// Pass through all the top-level exports, allows `import {version} from "pino"`
Expand All @@ -820,9 +820,9 @@ export type Level = pino.Level;
export type LevelOrString = pino.LevelOrString;
export type LevelWithSilent = pino.LevelWithSilent;
export type LevelWithSilentOrString = pino.LevelWithSilentOrString;
export type LevelChangeEventListener = pino.LevelChangeEventListener;
export type LevelChangeEventListener<CustomLevels extends { [key: string]: number; }> = pino.LevelChangeEventListener<CustomLevels>;
export type LogDescriptor = pino.LogDescriptor;
export type Logger<Options = LoggerOptions> = pino.Logger<Options>;
export type Logger<CustomLevels extends Record<string, number> = {}> = pino.Logger<CustomLevels>;
export type SerializedError = pino.SerializedError;
export type SerializerFn = pino.SerializerFn;
export type SerializedRequest = pino.SerializedRequest;
Expand All @@ -831,12 +831,12 @@ export type WriteFn = pino.WriteFn;

// Interfaces
export interface BaseLogger extends pino.BaseLogger {}
export interface ChildLoggerOptions extends pino.ChildLoggerOptions {}
export interface ChildLoggerOptions<CustomLevels extends Record<string, number>> extends pino.ChildLoggerOptions<CustomLevels> {}
export interface DestinationStream extends pino.DestinationStream {}
export interface LevelMapping extends pino.LevelMapping {}
export interface LogEvent extends pino.LogEvent {}
export interface LogFn extends pino.LogFn {}
export interface LoggerOptions extends pino.LoggerOptions {}
export interface LoggerOptions<CustomLevels extends Record<string, number>> extends pino.LoggerOptions<CustomLevels> {}
export interface MultiStreamOptions extends pino.MultiStreamOptions {}
export interface MultiStreamRes<TLevel = Level> extends pino.MultiStreamRes<TLevel> {}
export interface StreamEntry<TLevel = Level> extends pino.StreamEntry<TLevel> {}
Expand Down
20 changes: 20 additions & 0 deletions test/types/pino.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ cclog3.childLevel('')
// child itself
cclog3.childLevel2('')

const ccclog3 = clog3.child({})
expectError(ccclog3.nonLevel(''))

const withChildCallback = pino({
onChild: (child: Logger) => {}
})
Expand All @@ -343,3 +346,20 @@ const fn = (logger: Pick<CustomLevelLogger, CustomLevelLoggerLevels>) => {}
const customLevelChildLogger = customLevelLogger.child({ name: "child" })

fn(customLevelChildLogger); // missing foo typing

// unknown option
expectError(
pino({
hello: 'world'
})
);

// unknown option
expectError(
pino({
hello: 'world',
customLevels: {
'log': 30
}
})
);
Loading