refactor(miniprogram): 消灭全部 any 类型 — 32处 → 0 (E3-1)
- catch (err: any) → catch (err: unknown) + instanceof Error 类型缩窄(6 文件 13 处) - BLE 回调类型提取 BLEScanResult/BLEConnectionChangeResult/BLECharacteristicChangeResult/BLEServiceItem - BLEManager 7 处 any 注解替换为具体接口类型 - request.ts method as any → method as ValidMethod 字面量联合类型 - appointment ScheduleItem 接口定义替代 any[] - Taro.requestSubscribeMessage 使用类型断言替代 as any - globalThis.__hms 使用 Record<string, unknown> - TrendChart Canvas/useRef 保留 eslint-disable(微信 API 限制) - 0 TS 错误,119 测试通过
This commit is contained in:
@@ -37,6 +37,16 @@ interface TimeSlot {
|
||||
available_count: number;
|
||||
}
|
||||
|
||||
interface ScheduleItem {
|
||||
date?: string;
|
||||
appointment_date?: string;
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
available_count?: number;
|
||||
max_appointments?: number;
|
||||
current_appointments?: number;
|
||||
}
|
||||
|
||||
export default function AppointmentCreate() {
|
||||
const [currentStep, setCurrentStep] = useState(0);
|
||||
const [department, setDepartment] = useState('');
|
||||
@@ -47,7 +57,7 @@ export default function AppointmentCreate() {
|
||||
const [reason, setReason] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { safeSetTimeout } = useSafeTimeout();
|
||||
const [schedules, setSchedules] = useState<any[]>([]);
|
||||
const [schedules, setSchedules] = useState<ScheduleItem[]>([]);
|
||||
const [timeSlots, setTimeSlots] = useState<TimeSlot[]>([]);
|
||||
const modeClass = useElderClass();
|
||||
|
||||
@@ -55,7 +65,7 @@ export default function AppointmentCreate() {
|
||||
|
||||
const scheduledDates = useMemo(() => {
|
||||
if (!schedules) return new Set<string>();
|
||||
return new Set(schedules.map((s: any) => s.date || s.appointment_date));
|
||||
return new Set(schedules.map((s) => s.date || s.appointment_date || ''));
|
||||
}, [schedules]);
|
||||
|
||||
const onSelectDept = useCallback(async (dept: string) => {
|
||||
@@ -91,12 +101,12 @@ export default function AppointmentCreate() {
|
||||
setAppointmentDate(date);
|
||||
setTimeSlot('');
|
||||
const daySlots = schedules
|
||||
.filter((s: any) => (s.date || s.appointment_date) === date)
|
||||
.map((s: any) => ({
|
||||
.filter((s) => (s.date || s.appointment_date) === date)
|
||||
.map((s) => ({
|
||||
start_time: s.start_time || '',
|
||||
end_time: s.end_time || '',
|
||||
label: `${s.start_time || ''}-${s.end_time || ''}`,
|
||||
available_count: s.available_count ?? (s.max_appointments - (s.current_appointments || 0)),
|
||||
available_count: s.available_count ?? (s.max_appointments ?? 0) - (s.current_appointments ?? 0),
|
||||
}));
|
||||
setTimeSlots(daySlots);
|
||||
}, [schedules]);
|
||||
@@ -129,12 +139,12 @@ export default function AppointmentCreate() {
|
||||
const tmplId = TEMPLATE_IDS.APPOINTMENT_REMINDER;
|
||||
if (tmplId) {
|
||||
try {
|
||||
await (Taro.requestSubscribeMessage as any)({ tmplIds: [tmplId] });
|
||||
await (Taro as { requestSubscribeMessage: (opts: { tmplIds: string[] }) => Promise<unknown> }).requestSubscribeMessage({ tmplIds: [tmplId] });
|
||||
} catch { /* 用户拒绝 */ }
|
||||
}
|
||||
safeSetTimeout(() => Taro.navigateBack(), 1500);
|
||||
} catch (err: any) {
|
||||
const msg = err?.message || '预约失败';
|
||||
} catch (err: unknown) {
|
||||
const msg = err instanceof Error ? err.message : '预约失败';
|
||||
Taro.showToast({ title: msg.length > 20 ? msg.slice(0, 20) : msg, icon: 'none' });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function ConsultationCreate() {
|
||||
if (doctorsLoaded) return;
|
||||
try {
|
||||
const res = await listDoctors();
|
||||
const items = (res.data || []).map((d: any) => ({ id: d.id, name: d.name }));
|
||||
const items = (res.data || []).map((d: { id: string; name: string }) => ({ id: d.id, name: d.name }));
|
||||
setDoctorList(items);
|
||||
setDoctorsLoaded(true);
|
||||
} catch (err) {
|
||||
|
||||
@@ -86,8 +86,8 @@ export default function Login() {
|
||||
setNeedBind(true);
|
||||
Taro.showToast({ title: '请授权手机号完成绑定', icon: 'none' });
|
||||
}
|
||||
} catch (err: any) {
|
||||
const msg = err?.message || '登录失败,请重试';
|
||||
} catch (err: unknown) {
|
||||
const msg = err instanceof Error ? err.message : '登录失败,请重试';
|
||||
Taro.showToast({ title: msg.substring(0, 20), icon: 'none', duration: 3000 });
|
||||
}
|
||||
};
|
||||
@@ -104,8 +104,8 @@ export default function Login() {
|
||||
if (success) {
|
||||
navigateAfterLogin();
|
||||
}
|
||||
} catch (err: any) {
|
||||
Taro.showToast({ title: err?.message || '登录失败', icon: 'none' });
|
||||
} catch (err: unknown) {
|
||||
Taro.showToast({ title: err instanceof Error ? err.message : '登录失败', icon: 'none' });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,10 +120,10 @@ export default function Login() {
|
||||
if (success) {
|
||||
navigateAfterLogin();
|
||||
}
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
Taro.showModal({
|
||||
title: '绑定手机号失败',
|
||||
content: err?.message || '绑定失败',
|
||||
content: err instanceof Error ? err.message : '绑定失败',
|
||||
confirmText: '重新登录',
|
||||
cancelText: '取消',
|
||||
success: (res) => { if (res.confirm) setNeedBind(false); },
|
||||
|
||||
@@ -21,7 +21,7 @@ function InputField({ label, value, placeholder, type = 'digit', onChange }: {
|
||||
<Text className='form-label'>{label}</Text>
|
||||
<Input
|
||||
className='form-input'
|
||||
type={type as any}
|
||||
type={type as 'digit' | 'number' | 'text'}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onInput={(e) => onChange(e.detail.value)}
|
||||
|
||||
@@ -111,7 +111,7 @@ export default function PrescriptionCreate() {
|
||||
<Text className='form-label'>{label}</Text>
|
||||
<Input
|
||||
className='form-input'
|
||||
type={type as any}
|
||||
type={type as 'digit' | 'number' | 'text'}
|
||||
placeholder={placeholder}
|
||||
value={form[field]}
|
||||
onInput={(e) => updateField(field, e.detail.value)}
|
||||
|
||||
@@ -66,9 +66,9 @@ export default function DeviceSync() {
|
||||
setLastSyncAt(scheduler.getLastSyncAt());
|
||||
|
||||
// 检查是否有未上传的缓冲数据
|
||||
const buffer = (bleManager as any).dataBuffer;
|
||||
const buffer = (bleManager as unknown as { dataBuffer?: Map<string, number> }).dataBuffer;
|
||||
if (buffer) {
|
||||
setPendingCount(buffer.size());
|
||||
setPendingCount(buffer.size);
|
||||
}
|
||||
|
||||
// 自动同步:超过间隔时尝试上传缓冲数据
|
||||
@@ -105,8 +105,8 @@ export default function DeviceSync() {
|
||||
setErrorMsg('未发现支持的设备,请确认设备已开启蓝牙并靠近手机');
|
||||
}
|
||||
setPageState('idle');
|
||||
} catch (e: any) {
|
||||
setErrorMsg(e.message || '扫描失败');
|
||||
} catch (e: unknown) {
|
||||
setErrorMsg(e instanceof Error ? e.message : '扫描失败');
|
||||
setPageState('error');
|
||||
}
|
||||
}, []);
|
||||
@@ -118,8 +118,8 @@ export default function DeviceSync() {
|
||||
try {
|
||||
await getBleManager().connect(device);
|
||||
setPageState('connected');
|
||||
} catch (e: any) {
|
||||
setErrorMsg(e.message || '连接失败');
|
||||
} catch (e: unknown) {
|
||||
setErrorMsg(e instanceof Error ? e.message : '连接失败');
|
||||
setPageState('error');
|
||||
}
|
||||
}, []);
|
||||
@@ -169,8 +169,8 @@ export default function DeviceSync() {
|
||||
setErrorMsg(result.error || '同步失败');
|
||||
setPageState('error');
|
||||
}
|
||||
} catch (e: any) {
|
||||
setErrorMsg(e.message || '同步失败');
|
||||
} catch (e: unknown) {
|
||||
setErrorMsg(e instanceof Error ? e.message : '同步失败');
|
||||
setPageState('error');
|
||||
}
|
||||
}, [currentPatient, selectedDevice, liveReadings, returnTo]);
|
||||
|
||||
@@ -147,7 +147,7 @@ export default function HealthInput() {
|
||||
|
||||
const input = BP_INDICATORS.includes(currentIndicator)
|
||||
? { indicator_type: currentIndicator as 'blood_pressure' | 'blood_pressure_evening', value: parseFloat(systolic), extra: { systolic: parseFloat(systolic), diastolic: parseFloat(diastolic) } }
|
||||
: { indicator_type: currentIndicator as any, value: parseFloat(value) };
|
||||
: { indicator_type: currentIndicator as 'heart_rate' | 'blood_sugar_fasting' | 'blood_sugar_postprandial' | 'weight' | 'temperature', value: parseFloat(value) };
|
||||
|
||||
const valueResult = valueCheck.safeParse(input.value);
|
||||
if (!valueResult.ok) {
|
||||
|
||||
@@ -43,8 +43,8 @@ export default function EventsPage() {
|
||||
await pointsApi.registerEvent(event.id);
|
||||
Taro.showToast({ title: '报名成功', icon: 'success' });
|
||||
loadEvents();
|
||||
} catch (err: any) {
|
||||
const msg = err?.message || '报名失败';
|
||||
} catch (err: unknown) {
|
||||
const msg = err instanceof Error ? err.message : '报名失败';
|
||||
Taro.showToast({ title: msg.substring(0, 20), icon: 'none' });
|
||||
} finally {
|
||||
setRegistering(null);
|
||||
|
||||
@@ -55,7 +55,7 @@ export default function FollowUpDetail() {
|
||||
trackEvent('followup_submit', { task_id: id });
|
||||
const tmplId = TEMPLATE_IDS.FOLLOWUP_REMINDER;
|
||||
if (tmplId) {
|
||||
try { await (Taro.requestSubscribeMessage as any)({ tmplIds: [tmplId] }); } catch { /* 用户拒绝 */ }
|
||||
try { await (Taro as { requestSubscribeMessage: (opts: { tmplIds: string[] }) => Promise<unknown> }).requestSubscribeMessage({ tmplIds: [tmplId] }); } catch { /* 用户拒绝 */ }
|
||||
}
|
||||
setContent('');
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user