From 5c1d44b9d655e118aec80103c20f2f76e85dd8da Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Wed, 28 Jul 2021 21:09:44 -0700 Subject: [PATCH] fix(shared): support custom .toString() in text interpolation again Vue 2 did this, but this functionality was quietly removed from Vue 3 as a side effect of 3c60d40827f65cbf. Closes #3944. --- packages/shared/__tests__/toDisplayString.spec.ts | 14 +++++++++++++- packages/shared/src/toDisplayString.ts | 11 +++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/shared/__tests__/toDisplayString.spec.ts b/packages/shared/__tests__/toDisplayString.spec.ts index f9e20841e49..8e76c4322f9 100644 --- a/packages/shared/__tests__/toDisplayString.spec.ts +++ b/packages/shared/__tests__/toDisplayString.spec.ts @@ -31,10 +31,22 @@ describe('toDisplayString', () => { }) ).toBe(JSON.stringify({ n: 1, np: 2 }, null, 2)) }) + + test('objects with custom toString', () => { + class TestClass { + toString() { + return 'foo' + } + } + const instance = new TestClass() + expect(toDisplayString(instance)).toBe('foo') + const obj = { toString: () => 'bar' } + expect(toDisplayString(obj)).toBe('bar') + }) test('native objects', () => { const div = document.createElement('div') - expect(toDisplayString(div)).toBe(`"[object HTMLDivElement]"`) + expect(toDisplayString(div)).toBe('[object HTMLDivElement]') expect(toDisplayString({ div })).toMatchInlineSnapshot(` "{ \\"div\\": \\"[object HTMLDivElement]\\" diff --git a/packages/shared/src/toDisplayString.ts b/packages/shared/src/toDisplayString.ts index bcfe1a90721..a374f525d6b 100644 --- a/packages/shared/src/toDisplayString.ts +++ b/packages/shared/src/toDisplayString.ts @@ -1,4 +1,11 @@ -import { isArray, isMap, isObject, isPlainObject, isSet } from './index' +import { + isArray, + isMap, + isObject, + isPlainObject, + isSet, + objectToString +} from './index' /** * For converting {{ interpolation }} values to displayed strings. @@ -7,7 +14,7 @@ import { isArray, isMap, isObject, isPlainObject, isSet } from './index' export const toDisplayString = (val: unknown): string => { return val == null ? '' - : isObject(val) + : isArray(val) || (isObject(val) && val.toString === objectToString) ? JSON.stringify(val, replacer, 2) : String(val) }