-
Notifications
You must be signed in to change notification settings - Fork 886
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix: typescript types * fix: tests * fix: comment * fix: tests * fix: tests * docs: typescript info * docs: add more docs * docs: update typescript.md * chore: update tsd dep * chore: remove yarn * fix: tests * fix: readme
- Loading branch information
Showing
6 changed files
with
302 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Usage With TypeScript | ||
|
||
## Introduction | ||
|
||
If you are using TypeScript, Pino should work out of the box without any additional configuration. This is because even though Pino is written in JavaScript, it includes [a TypeScript definitions file](https://github.com/pinojs/pino/blob/master/pino.d.ts) as part of its bundle. | ||
|
||
In new TypeScript projects, you will want to use the ESM import style, like this: | ||
|
||
```ts | ||
import pino from "pino"; | ||
|
||
const logger = pino(); | ||
|
||
logger.info('hello world'); | ||
``` | ||
|
||
Some edge-cases are listed below. | ||
|
||
## String Interpolation | ||
|
||
The TypeScript definitions are configured to detect string interpolation arguments like this: | ||
|
||
```ts | ||
const foo: string = getFoo(); | ||
logger.info("foo: %s", foo); | ||
``` | ||
|
||
In this case, `%s` refers to a string, as explained in the [documentation for logging method parameters](https://getpino.io/#/docs/api?id=logger). | ||
|
||
If you use a string interpolation placeholder without a corresponding argument or with an argument of the wrong type, the TypeScript compiler will throw an error. For example: | ||
|
||
```ts | ||
const foo: string = getFoo(); | ||
logger.info("foo: %s"); // Error: Missing an expected argument. | ||
logger.info("foo: %d", foo); // Error: `foo` is not a number. | ||
``` | ||
|
||
## Validating the Object | ||
|
||
Pino supports [logging both strings and objects](https://getpino.io/#/docs/api?id=logger). If you are passing an object to a Pino logger, you might want to validate that the object is in the correct shape. You can do this with the [`satisfies` operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html) in the same way that you would in other kinds of TypeScript code. For example: | ||
|
||
```ts | ||
const myObject = { | ||
foo: "someString", | ||
bar: "someString", | ||
} satisfies MyObject; | ||
logger.info(strictShape); | ||
``` | ||
|
||
Note that passing the object type as the first generic parameter to the logger is no longer supported. | ||
|
||
## Higher Order Functions | ||
|
||
Unfortunately, the type definitions for the Pino logger may not work properly when invoking them from a higher order function. For example: | ||
|
||
```ts | ||
setTimeout(logger, 1000, "A second has passed!"); | ||
``` | ||
|
||
This is a valid invocation of the logger (i.e. simply passing a single string argument), but TypeScript will throw a spurious error. To work around this, one solution is to wrap the function invocation like this: | ||
|
||
```ts | ||
setTimeout(() => { | ||
logger("A second has passed!"); | ||
}, 1000); | ||
``` | ||
|
||
Another solution would be to perform a manual type assertion like this: | ||
|
||
```ts | ||
setTimeout(logger as (message: string) => void, 1000, "A second has passed!"); | ||
``` | ||
|
||
Obviously, using type assertions makes your code less safe, so use the second solution with care. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import pino from "../../pino"; | ||
|
||
// This file tests the "LogFn" interface, located in the "pino.d.ts" file. | ||
|
||
const logger = pino(); | ||
|
||
// ---------------- | ||
// 1 Argument Tests | ||
// ---------------- | ||
|
||
// Works. | ||
logger.info("Testing a basic string log message."); | ||
logger.info("Using an unsupported string interpolation pattern like %x should not cause an error."); | ||
logger.info({ foo: "foo" }); | ||
logger.info(123); | ||
logger.info(true); | ||
|
||
// Fails because these types are not supported. | ||
// @ts-expect-error | ||
logger.info(() => {}); | ||
// @ts-expect-error | ||
logger.info(Symbol("foo")); | ||
|
||
// ------------------------------------------- | ||
// 2 Argument Tests (with string as first arg) | ||
// ------------------------------------------- | ||
|
||
// Works | ||
logger.info("Message with an interpolation value: %s", "foo"); | ||
logger.info("Message with an interpolation value: %d", 123); | ||
logger.info("Message with an interpolation value: %o", {}); | ||
|
||
// Fails because there isn't supposed to be a second argument. | ||
// @ts-expect-error | ||
logger.info("Message with no interpolation value.", "foo"); | ||
|
||
// Fails because we forgot the second argument entirely. | ||
// @ts-expect-error | ||
logger.info("Message with an interpolation value: %s"); | ||
// @ts-expect-error | ||
logger.info("Message with an interpolation value: %d"); | ||
// @ts-expect-error | ||
logger.info("Message with an interpolation value: %o"); | ||
|
||
// Fails because we put the wrong type as the second argument. | ||
// @ts-expect-error | ||
logger.info("Message with an interpolation value: %s", 123); | ||
// @ts-expect-error | ||
logger.info("Message with an interpolation value: %d", "foo"); | ||
// @ts-expect-error | ||
logger.info("Message with an interpolation value: %o", "foo"); | ||
|
||
// ------------------------------------------- | ||
// 2 Argument Tests (with object as first arg) | ||
// ------------------------------------------- | ||
|
||
// Works | ||
logger.info({ foo: "foo" }, "bar"); | ||
|
||
// Fails because the second argument must be a string. | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, 123); | ||
|
||
// ------------------------------------------- | ||
// 3 Argument Tests (with string as first arg) | ||
// ------------------------------------------- | ||
|
||
// Works | ||
logger.info("Message with two interpolation values: %s %s", "foo", "bar"); | ||
logger.info("Message with two interpolation values: %d %d", 123, 456); | ||
logger.info("Message with two interpolation values: %o %o", {}, {}); | ||
|
||
// Fails because we forgot the third argument entirely. | ||
// @ts-expect-error | ||
logger.info("Message with two interpolation values: %s %s", "foo"); | ||
// @ts-expect-error | ||
logger.info("Message with two interpolation values: %d %d", 123); | ||
// @ts-expect-error | ||
logger.info("Message with two interpolation values: %o %o", {}); | ||
|
||
// Works | ||
logger.info("Message with two interpolation values of different types: %s %d", "foo", 123); | ||
logger.info("Message with two interpolation values of different types: %d %o", 123, {}); | ||
|
||
// Fails because we put the wrong type as the third argument. | ||
// @ts-expect-error | ||
logger.info("Message with two interpolation values of different types: %s %d", "foo", "bar"); | ||
// @ts-expect-error | ||
logger.info("Message with two interpolation values of different types: %d %o", 123, 456); | ||
|
||
// ------------------------------------------- | ||
// 3 Argument Tests (with object as first arg) | ||
// ------------------------------------------- | ||
|
||
// Works | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %s", "foo"); | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %d", 123); | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %o", {}); | ||
|
||
// Fails because there isn't supposed to be a third argument. | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with no interpolation value.", "foo"); | ||
|
||
// Fails because we forgot the third argument entirely. | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %s"); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %d"); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %o"); | ||
|
||
// Fails because we put the wrong type as the third argument. | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %s", 123); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %d", "foo"); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with an interpolation value: %o", "foo"); | ||
|
||
// ------------------------------------------- | ||
// 4 Argument Tests (with object as first arg) | ||
// ------------------------------------------- | ||
|
||
// Works | ||
logger.info({ foo: "foo" }, "Message with two interpolation values: %s %s", "foo", "bar"); | ||
logger.info({ foo: "foo" }, "Message with two interpolation values: %d %d", 123, 456); | ||
logger.info({ foo: "foo" }, "Message with two interpolation values: %o %o", {}, {}); | ||
|
||
// Fails because we forgot the third argument entirely. | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with two interpolation values: %s %s", "foo"); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with two interpolation values: %d %d", 123); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with two interpolation values: %o %o", {}); | ||
|
||
// Works | ||
logger.info({ foo: "foo" }, "Message with two interpolation values of different types: %s %d", "foo", 123); | ||
logger.info({ foo: "foo" }, "Message with two interpolation values of different types: %d %o", 123, {}); | ||
|
||
// Fails because we put the wrong type as the fourth argument. | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with two interpolation values of different types: %s %d", "foo", "bar"); | ||
// @ts-expect-error | ||
logger.info({ foo: "foo" }, "Message with two interpolation values of different types: %d %o", 123, 456); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters