-
-
Notifications
You must be signed in to change notification settings - Fork 81
Description
Describe the bug
The TypeScript type for getChanges is incorrect.
GetChangesResults.upsertionChanges[i].record is typed as HealthConnectRecord, but at runtime it has the shape of HealthConnectRecordResult (including metadata, recordType, etc.). This causes type errors when using the result as a WeightRecord.
To Reproduce
Steps to reproduce the behavior:
- Call
getChangeswith aWeightrecord type:const changes = await getChanges({ changesToken, recordTypes: ['Weight'], }); samples.push( ...changes.upsertionChanges .map(({ record }) => record) .filter( (record): record is WeightRecord => record.recordType === 'Weight', ) .map((record) => this.normalizeWeight(record)), );
normalizeWeightexpects aWeightRecord:private normalizeWeight(record: WeightRecord): BodyMassSample { const timestamp = new Date(record.time).toISOString(); const kilograms = this.toKilograms(record.weight); const value = Number(kilograms.toFixed(3)); const hash = buildSampleHash(timestamp, value); // ... }
- TypeScript reports a type error when passing
recordintonormalizeWeight, becauserecordis typed asHealthConnectRecord. - Log
changes.upsertionChanges[0].recordand see the actual runtime shape:{ metadata: { clientRecordVersion: 0, dataOrigin: 'com.google.android.apps.fitness', id: '', lastModifiedTime: '2025-11-26T05:06:23.219Z', recordingMethod: 3, }, recordType: 'Weight', time: '2025-11-15T05:06:00Z', weight: { inGrams: 67099.9984741211, inKilograms: 67.0999984741211, inMicrograms: 67099998474.12109, inMilligrams: 67099998.474121094, inOunces: 2366.8830538972475, inPounds: 147.9301745620657, }, }
Expected behavior
getChanges typings should match the runtime data.
GetChangesResults.upsertionChanges[i].record should be typed as HealthConnectRecordResult so that WeightRecord (and other specific record result types) can be used without unsafe casts.
Proposed change
Update the interface as follows:
// Current
export interface GetChangesResults {
upsertionChanges: Array<{ record: HealthConnectRecord }>;
deletionChanges: Array<{ recordId: string }>;
nextChangesToken: string;
changesTokenExpired: boolean;
hasMore: boolean;
}
// Suggested
export interface GetChangesResults {
upsertionChanges: Array<{ record: HealthConnectRecordResult }>;
deletionChanges: Array<{ recordId: string }>;
nextChangesToken: string;
changesTokenExpired: boolean;
hasMore: boolean;
}Happy to open a PR with this change if desired.
Minimal Reproducible
The code snippets above should reproduce the issue in a fresh project that calls getChanges for Weight records.
Environment:
- Health Connect Version: 3.5.0
- React Native Version: 0.81.5
- New architecture enabled: Yes
- Using Expo
- Android API Level: 36