Skip to content

Commit

Permalink
Merge pull request #120 from morpho-org/fix/format-typing
Browse files Browse the repository at this point in the history
fix(format): allow undefined decimals
  • Loading branch information
oumar-fall authored Oct 8, 2024
2 parents fadb96c + 2f586a0 commit f97451e
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 8 deletions.
4 changes: 2 additions & 2 deletions packages/morpho-ts/src/format/format/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The `format` object provides access to different formatters:
### Usage

Each formatter can be accessed through the `format` object and provides chainable methods to customize the output. The formatted value can be obtained calling `.of(value)` for `number` or `.of(value, decimals)` for `bigint`.
The return value will retain the nullability of the input value, unless a `.default()` method is applied (refer to [Number Formatter](#2-number-formatter) for details).
The return value will retain the nullability of the input value (giving priority to `value` over `decimals` for bigints, if none is defined), unless a `.default()` method is applied (refer to [Number Formatter](#2-number-formatter) for details).

> [!Tip]
> You can store the populated `of` function in a custom formatter:
Expand Down Expand Up @@ -71,7 +71,7 @@ const numberValue = format.number.of(123.45); // "123.45"
- `.unit(string)`: Adds a unit to the number (e.g., "$", "%").
- `.locale(string)`: Formats the number according to the specified locale.
- `.readable()`: Makes the value more readable for small numbers.
- `.default(string)`: Sets a default value in case value is `null` or `undefined`.
- `.default(string)`: Sets a default value in case `value` (or `decimals`) is `null` or `undefined`.

### 3. Commas Formatter

Expand Down
90 changes: 90 additions & 0 deletions packages/morpho-ts/src/format/format/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ describe("format", () => {
expect(format.hex.default("default").of(undefined)).toEqual("default");
expect(format.hex.default("default").of(null)).toEqual("default");
});
it("with nullable values", () => {
expect(format.hex.of(undefined)).toEqual(undefined);
expect(format.hex.of(null)).toEqual(null);
});
});
describe("should properly format bigint in hex format", () => {
it("without option", () => {
Expand All @@ -26,6 +30,20 @@ describe("format", () => {
"default",
);
expect(format.hex.default("default").of(null, 18)).toEqual("default");
expect(format.hex.default("default").of(bigint, undefined)).toEqual(
"default",
);
expect(format.hex.default("default").of(bigint, null)).toEqual(
"default",
);
});
it("with nullable values", () => {
expect(format.hex.of(undefined, decimals)).toEqual(undefined);
expect(format.hex.of(null, decimals)).toEqual(null);
expect(format.hex.of(bigint, undefined)).toEqual(undefined);
expect(format.hex.of(bigint, null)).toEqual(null);
expect(format.hex.of(null, undefined)).toEqual(null);
expect(format.hex.of(undefined, null)).toEqual(undefined);
});
});
});
Expand Down Expand Up @@ -76,6 +94,10 @@ describe("format", () => {
);
expect(format.number.default("default").of(null)).toEqual("default");
});
it("with nullable values", () => {
expect(format.number.of(undefined)).toEqual(undefined);
expect(format.number.of(null)).toEqual(null);
});
});
describe("should properly format bigint in number format", () => {
it("without option", () => {
Expand Down Expand Up @@ -126,6 +148,20 @@ describe("format", () => {
expect(format.number.default("default").of(null, 18)).toEqual(
"default",
);
expect(format.number.default("default").of(bigint, undefined)).toEqual(
"default",
);
expect(format.number.default("default").of(bigint, null)).toEqual(
"default",
);
});
it("with nullable values", () => {
expect(format.number.of(undefined, decimals)).toEqual(undefined);
expect(format.number.of(null, decimals)).toEqual(null);
expect(format.number.of(bigint, undefined)).toEqual(undefined);
expect(format.number.of(bigint, null)).toEqual(null);
expect(format.number.of(null, undefined)).toEqual(null);
expect(format.number.of(undefined, null)).toEqual(undefined);
});
});
});
Expand Down Expand Up @@ -170,6 +206,10 @@ describe("format", () => {
);
expect(format.short.default("default").of(null)).toEqual("default");
});
it("with nullable values", () => {
expect(format.short.of(undefined)).toEqual(undefined);
expect(format.short.of(null)).toEqual(null);
});
});
describe("should properly format bigint in short format", () => {
it("without option", () => {
Expand Down Expand Up @@ -230,6 +270,20 @@ describe("format", () => {
"default",
);
expect(format.short.default("default").of(null, 18)).toEqual("default");
expect(format.short.default("default").of(bigint, undefined)).toEqual(
"default",
);
expect(format.short.default("default").of(bigint, null)).toEqual(
"default",
);
});
it("with nullable values", () => {
expect(format.short.of(undefined, decimals)).toEqual(undefined);
expect(format.short.of(null, decimals)).toEqual(null);
expect(format.short.of(bigint, undefined)).toEqual(undefined);
expect(format.short.of(bigint, null)).toEqual(null);
expect(format.short.of(null, undefined)).toEqual(null);
expect(format.short.of(undefined, null)).toEqual(undefined);
});
});
});
Expand Down Expand Up @@ -271,6 +325,10 @@ describe("format", () => {
);
expect(format.commas.default("default").of(null)).toEqual("default");
});
it("with nullable values", () => {
expect(format.commas.of(undefined)).toEqual(undefined);
expect(format.commas.of(null)).toEqual(null);
});
});
describe("should properly format bigint in commas format", () => {
it("without option", () => {
Expand Down Expand Up @@ -322,6 +380,20 @@ describe("format", () => {
expect(format.commas.default("default").of(null, 18)).toEqual(
"default",
);
expect(format.commas.default("default").of(bigint, undefined)).toEqual(
"default",
);
expect(format.commas.default("default").of(bigint, null)).toEqual(
"default",
);
});
it("with nullable values", () => {
expect(format.commas.of(undefined, decimals)).toEqual(undefined);
expect(format.commas.of(null, decimals)).toEqual(null);
expect(format.commas.of(bigint, undefined)).toEqual(undefined);
expect(format.commas.of(bigint, null)).toEqual(null);
expect(format.commas.of(null, undefined)).toEqual(null);
expect(format.commas.of(undefined, null)).toEqual(undefined);
});
});
});
Expand Down Expand Up @@ -362,6 +434,10 @@ describe("format", () => {
);
expect(format.percent.default("default").of(null)).toEqual("default");
});
it("with nullable values", () => {
expect(format.percent.of(undefined)).toEqual(undefined);
expect(format.percent.of(null)).toEqual(null);
});
});
describe("should properly format bigint in percent format", () => {
it("without option", () => {
Expand Down Expand Up @@ -409,6 +485,20 @@ describe("format", () => {
expect(format.percent.default("default").of(null, 18)).toEqual(
"default",
);
expect(format.percent.default("default").of(bigint, undefined)).toEqual(
"default",
);
expect(format.percent.default("default").of(bigint, null)).toEqual(
"default",
);
});
it("with nullable values", () => {
expect(format.percent.of(undefined, decimals)).toEqual(undefined);
expect(format.percent.of(null, decimals)).toEqual(null);
expect(format.percent.of(bigint, undefined)).toEqual(undefined);
expect(format.percent.of(bigint, null)).toEqual(null);
expect(format.percent.of(null, undefined)).toEqual(null);
expect(format.percent.of(undefined, null)).toEqual(undefined);
});
});
});
Expand Down
19 changes: 13 additions & 6 deletions packages/morpho-ts/src/format/format/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,10 @@ function formatBI(
}

type FormatterWithDefault<F extends BaseFormatter> = {
of(value: bigint | null | undefined, decimals: number): string;
of(
value: bigint | null | undefined,
decimals: number | null | undefined,
): string;
of(value: number | null | undefined): string;
} & {
[K in keyof Omit<F, "of">]: F[K] extends (...args: infer A) => F
Expand All @@ -284,15 +287,19 @@ export abstract class BaseFormatter {
return this as FormatterWithDefault<this>;
}

of<T extends bigint | null | undefined>(
of<T extends bigint | null | undefined, D extends number | null | undefined>(
value: T,
decimals: number,
): Exclude<T, bigint> | string;
decimals: D,
): Exclude<T, bigint> | Exclude<D, number> | string;
of<T extends number | null | undefined>(
value: T,
): Exclude<T, number> | string;
of(value: bigint | number, decimals?: number) {
if (value == null) return this._options.default ?? value;
of(
value: bigint | number | null | undefined,
decimals?: number | null | undefined,
) {
if (value == null || (typeof value === "bigint" && decimals == null))
return this._options.default ?? (value == null ? value : decimals);

if (typeof value === "number") {
const str = value.toString();
Expand Down

0 comments on commit f97451e

Please sign in to comment.