refactor: improve type safety for translations by replacing any types with specific parameters and node types

This commit is contained in:
Ivan Mercedes 2026-07-07 20:55:21 -04:00
parent eeea478315
commit a6596de2c9
4 changed files with 8 additions and 8 deletions

View File

@ -198,7 +198,7 @@ export function InviteMemberDialog({
{t.rich('inviteCreatedDesc', { {t.rich('inviteCreatedDesc', {
role: tRoles(result.role), role: tRoles(result.role),
days: result.expiresInDays, days: result.expiresInDays,
bold: (chunks: any) => <strong>{chunks}</strong> bold: (chunks: React.ReactNode) => <strong>{chunks}</strong>
})} })}
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
@ -305,7 +305,7 @@ export function InviteMemberDialog({
<SelectContent> <SelectContent>
{EXPIRY_OPTIONS.map((opt) => ( {EXPIRY_OPTIONS.map((opt) => (
<SelectItem key={opt.value} value={opt.value}> <SelectItem key={opt.value} value={opt.value}>
{t(opt.labelKey as any)} {t(opt.labelKey as Parameters<typeof t>[0])}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@ -115,7 +115,7 @@ function fmtDate(iso: string): string {
}); });
} }
function fmtExpiresIn(iso: string, t: any): string { function fmtExpiresIn(iso: string, t: (key: string, values?: Record<string, unknown>) => string): string {
const ms = new Date(iso).getTime() - Date.now(); const ms = new Date(iso).getTime() - Date.now();
if (ms <= 0) return t('expired'); if (ms <= 0) return t('expired');
const days = Math.floor(ms / (24 * 60 * 60 * 1000)); const days = Math.floor(ms / (24 * 60 * 60 * 1000));
@ -579,7 +579,7 @@ export function MembersTab() {
<DialogDescription className="text-muted-foreground"> <DialogDescription className="text-muted-foreground">
{t.rich('removeDialogDesc', { {t.rich('removeDialogDesc', {
name: removingMember?.full_name || t('unnamed'), name: removingMember?.full_name || t('unnamed'),
bold: (chunks: any) => <strong>{chunks}</strong> bold: (chunks: React.ReactNode) => <strong>{chunks}</strong>
})} })}
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>

View File

@ -297,7 +297,7 @@ export function ProfileForm() {
{t.rich('emailChangeHint', { {t.rich('emailChangeHint', {
oldEmail: profile?.email || '', oldEmail: profile?.email || '',
newEmail: email, newEmail: email,
bold: (chunks: any) => <strong>{chunks}</strong> bold: (chunks: React.ReactNode) => <strong>{chunks}</strong>
})} })}
</span> </span>
</p> </p>

View File

@ -188,7 +188,7 @@ export function TagManager() {
<button <button
type="button" type="button"
onClick={() => confirmDelete(tag)} onClick={() => confirmDelete(tag)}
aria-label={t('deleteAria', { name: tag.name })} aria-label={t('deleteAria', { name: tag.name, bold: (chunks: React.ReactNode) => <strong>{chunks}</strong> })}
className="ml-0.5 rounded-full p-0.5 opacity-60 transition-opacity hover:bg-black/10 hover:opacity-100 dark:hover:bg-white/10" className="ml-0.5 rounded-full p-0.5 opacity-60 transition-opacity hover:bg-black/10 hover:opacity-100 dark:hover:bg-white/10"
> >
<X className="size-3" /> <X className="size-3" />
@ -221,7 +221,7 @@ export function TagManager() {
key={color.value} key={color.value}
type="button" type="button"
onClick={() => setSelectedColor(color.value)} onClick={() => setSelectedColor(color.value)}
aria-label={t('useColor', { color: t(`colors.${color.name}` as any) })} aria-label={t('useColor', { color: t(`colors.${color.name}` as Parameters<typeof t>[0]) })}
aria-pressed={selectedColor === color.value} aria-pressed={selectedColor === color.value}
className={cn( className={cn(
'size-6 rounded-md transition-transform hover:scale-110', 'size-6 rounded-md transition-transform hover:scale-110',
@ -229,7 +229,7 @@ export function TagManager() {
'outline outline-2 outline-offset-2 outline-primary', 'outline outline-2 outline-offset-2 outline-primary',
)} )}
style={{ backgroundColor: color.value }} style={{ backgroundColor: color.value }}
title={t(`colors.${color.name}` as any)} title={t(`colors.${color.name}` as Parameters<typeof t>[0])}
/> />
))} ))}
</div> </div>