Replies: 3 comments 4 replies
-
Hey @felixmosh! The only way to check whether something is a Dinero object is to "duck type" it. However, this isn't a silver bullet because you could have something else in your code that looks like a Dinero object but isn't one. There's no way to know in advance, only when you know the target codebase. That's why for now, I believe it's safer to keep this code userland. I would recommend creating your own utility, something like: function isDinero(maybeDineroObject) {
return (
maybeDineroObject.hasOwnProperty('calculator') &&
maybeDineroObject.hasOwnProperty('create') &&
maybeDineroObject.hasOwnProperty('toJSON')
);
} Keep in mind that these properties are internal, so I'd also recommend writing tests so nothing breaks when you upgrade. I'm moving this into a GitHub Discussion to keep it open, and since this is a feature request (and not a bug). If other users express the need for it, we can all chat about it over there and reconsider. |
Beta Was this translation helpful? Give feedback.
-
I think one challenge is getting this to work with libraries such as |
Beta Was this translation helpful? Give feedback.
-
I wrote some Zod schemas to accomplish this: export const dineroSchema = z.object({
calculator: z.object({
add: z.function(),
compare: z.function(),
decrement: z.function(),
increment: z.function(),
integerDivide: z.function(),
modulo: z.function(),
multiply: z.function(),
power: z.function(),
subtract: z.function(),
zero: z.function(),
}).strict(),
formatter: z.object({
toNumber: z.function(),
toString: z.function(),
}).strict(),
create: z.function(),
toJSON: z.function(),
}).strict()
export const dineroSnapshotSchema = z.object({
amount: z.number(),
currency: z.object({
code: z.string(),
base: z.number(),
exponent: z.number(),
}).strict(),
scale: z.number(),
}).strict()
export function isDinero(object: unknown): object is Dinero<number> {
return dineroSchema.safeParse(object).success
}
export function isDineroSnapshot(object: unknown): object is DineroSnapshot<number> {
return dineroSnapshotSchema.safeParse(object).success
} And some tests: describe('isDinero', () => {
test('returns true for Dinero objects', () => {
expect(isDinero(dinero({ amount: 0, scale: 0, currency: USD }))).toBe(true)
expect(isDinero(dinero({ amount: 123, scale: 2, currency: USD }))).toBe(true)
expect(isDinero(dinero({ amount: -123, scale: 2, currency: USD }))).toBe(true)
expect(isDinero(dinero({ amount: 12345678900, scale: 6, currency: USD }))).toBe(true)
expect(isDinero(dinero({ amount: -12345678900, scale: 6, currency: USD }))).toBe(true)
})
test('returns false for non-Dinero objects', () => {
expect(isDinero(undefined)).toBe(false)
expect(isDinero(null)).toBe(false)
expect(isDinero('')).toBe(false)
expect(isDinero('abc')).toBe(false)
expect(isDinero(123)).toBe(false)
expect(isDinero(0)).toBe(false)
expect(isDinero(1)).toBe(false)
expect(isDinero(-1)).toBe(false)
expect(isDinero({})).toBe(false)
expect(isDinero({ amount: 0, scale: 0, currency: USD })).toBe(false)
expect(isDinero(toSnapshot(dinero({ amount: 0, scale: 0, currency: USD })))).toBe(false)
expect(isDinero({ calculator: {} })).toBe(false)
expect(isDinero({ calculator: {}, formatter: {} })).toBe(false)
expect(isDinero({ calculator: {}, formatter: {}, create: () => null })).toBe(false)
expect(isDinero({ calculator: {}, formatter: {}, create: () => null, toJSON: () => null })).toBe(false)
})
})
describe('isDineroSnapshot', () => {
test('returns true for Dinero snapshots', () => {
expect(isDineroSnapshot(toSnapshot(dinero({ amount: 0, scale: 0, currency: USD })))).toBe(true)
expect(isDineroSnapshot(toSnapshot(dinero({ amount: 123, scale: 2, currency: USD })))).toBe(true)
expect(isDineroSnapshot(toSnapshot(dinero({ amount: -123, scale: 2, currency: USD })))).toBe(true)
expect(isDineroSnapshot(toSnapshot(dinero({ amount: 12345678900, scale: 6, currency: USD })))).toBe(true)
expect(isDineroSnapshot(toSnapshot(dinero({ amount: -12345678900, scale: 6, currency: USD })))).toBe(true)
expect(isDineroSnapshot({ amount: 0, scale: 0, currency: USD })).toBe(true)
expect(isDineroSnapshot({ amount: 0, scale: 2, currency: USD })).toBe(true)
expect(isDineroSnapshot({ amount: 123, scale: 2, currency: { code: 'USD', base: 10, exponent: 2 } })).toBe(true)
expect(isDineroSnapshot({ amount: -123, scale: 2, currency: { code: 'USD', base: 10, exponent: 2 } })).toBe(true)
})
test('returns false for non-Dinero snapshots', () => {
expect(isDineroSnapshot(undefined)).toBe(false)
expect(isDineroSnapshot(null)).toBe(false)
expect(isDineroSnapshot('')).toBe(false)
expect(isDineroSnapshot('abc')).toBe(false)
expect(isDineroSnapshot(123)).toBe(false)
expect(isDineroSnapshot(0)).toBe(false)
expect(isDineroSnapshot(1)).toBe(false)
expect(isDineroSnapshot(-1)).toBe(false)
expect(isDineroSnapshot({})).toBe(false)
expect(isDineroSnapshot(dinero({ amount: 0, scale: 0, currency: USD }))).toBe(false)
expect(isDineroSnapshot({ amount: 0 })).toBe(false)
expect(isDineroSnapshot({ amount: 0, scale: 0 })).toBe(false)
expect(isDineroSnapshot({ amount: 0, scale: 0, currency: {} })).toBe(false)
expect(isDineroSnapshot({ amount: 0, scale: 0, currency: { code: 'USD' } })).toBe(false)
expect(isDineroSnapshot({ amount: 0, scale: 0, currency: { code: 'USD', base: 10 } })).toBe(false)
expect(isDineroSnapshot({ amount: 0, scale: 0, currency: { code: 'USD', exponent: 2 } })).toBe(false)
expect(isDineroSnapshot({ amount: 0, scale: 0, currency: USD, calculator: {} })).toBe(false)
})
}) |
Beta Was this translation helpful? Give feedback.
-
I'm using i18next for translation & formatting prices / dates, in order to format an object, I need to check if it is a price object.
it can be really awesome if the lib will contain a utility function which will return
true
if it gets the dinero object.WDYT?
Beta Was this translation helpful? Give feedback.
All reactions