Skip to content

Commit 6f804b2

Browse files
os-zhuangclaude
andauthored
fix(plugin-view): coerce i18n tab-label helpers to string (TS2322) (#2721)
`useViewTabLabel()` (ViewTabBar) and `useViewLabel()` (ManageViewsDialog) returned the raw `t()` result, typed `string | object` by i18next. Their return values are rendered directly as React children and passed as aria-labels at ~35 sites, so vite build's dts pass emitted TS2322 (`string | object` not assignable to ReactNode). plugin-view has no type-check gate, so these did not fail the build — but if `t()` ever resolves a key to an object, React throws and white-screens. Coerce the resolved value with `String(v)` and annotate the helper's return type as `string`. Same "i18n/expression value is string|object, rendered raw → white-screen" class tracked separately from PR #2718. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 14cb729 commit 6f804b2

2 files changed

Lines changed: 8 additions & 4 deletions

File tree

packages/plugin-view/src/ManageViewsDialog.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ import type { ViewTabItem } from './ViewTabBar';
7171
function useViewLabel() {
7272
try {
7373
const { t } = useObjectTranslation();
74-
return (key: string, fallback: string, vars?: Record<string, unknown>) => {
74+
return (key: string, fallback: string, vars?: Record<string, unknown>): string => {
7575
const v = t(key, vars as any);
76-
return !v || v === key ? fallback : v;
76+
// i18next's `t()` is typed `string | object`; coerce so render sites and
77+
// aria-labels always receive a string (an object child white-screens React).
78+
return !v || v === key ? fallback : String(v);
7779
};
7880
} catch {
7981
return (_k: string, fallback: string) => fallback;

packages/plugin-view/src/ViewTabBar.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,11 @@ import { useObjectTranslation } from '@object-ui/react';
9292
function useViewTabLabel() {
9393
try {
9494
const { t } = useObjectTranslation();
95-
return (key: string, fallback: string, vars?: Record<string, unknown>) => {
95+
return (key: string, fallback: string, vars?: Record<string, unknown>): string => {
9696
const v = t(key, vars as any);
97-
return !v || v === key ? fallback : v;
97+
// i18next's `t()` is typed `string | object`; coerce so render sites and
98+
// aria-labels always receive a string (an object child white-screens React).
99+
return !v || v === key ? fallback : String(v);
98100
};
99101
} catch {
100102
return (_k: string, fallback: string) => fallback;

0 commit comments

Comments
 (0)