Problem
The typings declare InstallMode, SyncStatus, CheckFrequency and UpdateState as numeric enums. TypeScript therefore accepts reading them by value:
codePush.sync(options, (status) => {
console.log(codePush.SyncStatus[status]); // type-checks, but always undefined
});
At runtime these are plain objects without reverse keys (SyncStatus and CheckFrequency are object literals in src/CodePush.js; InstallMode and UpdateState come from src/native/NativeCodePush.ts), so the lookup above always gives undefined. An app hit this when it tried to report the sync status a failure happened after: the value was missing from every report.
Why this is not fixed in a patch release
Every way to make the typings and the runtime agree breaks someone. #207 tried the runtime side and was closed for that reason.
- Add reverse keys at runtime (what a compiled numeric enum does):
Object.keys, Object.values, Object.entries, for...in and object spread start returning the numeric keys too. An app that builds a list of statuses from Object.values(codePush.SyncStatus) silently gets the names mixed in. The change shows up only at runtime.
- Add reverse keys as non-enumerable properties: avoids the above, but it is an unusual shape for an enum, and the reason for it would not be obvious to the next reader.
- Change the typings to match the runtime: declare each one as a readonly object plus a type of its values, so the reverse lookup becomes a compile error. Comparisons,
switch, passing members as options, and annotations like let s: codePush.SyncStatus keep compiling. Code that uses a member as a type, such as let s: codePush.SyncStatus.UP_TO_DATE, has to change to typeof codePush.SyncStatus.UP_TO_DATE.
Proposal
Change the typings in the next major release. Of the options, it is the only one whose breakage surfaces at compile time instead of changing behavior quietly, and it leaves the runtime alone.
DeploymentStatus is a string enum, which TypeScript never reverse-maps, so it is not affected.
Problem
The typings declare
InstallMode,SyncStatus,CheckFrequencyandUpdateStateas numeric enums. TypeScript therefore accepts reading them by value:At runtime these are plain objects without reverse keys (
SyncStatusandCheckFrequencyare object literals insrc/CodePush.js;InstallModeandUpdateStatecome fromsrc/native/NativeCodePush.ts), so the lookup above always givesundefined. An app hit this when it tried to report the sync status a failure happened after: the value was missing from every report.Why this is not fixed in a patch release
Every way to make the typings and the runtime agree breaks someone. #207 tried the runtime side and was closed for that reason.
Object.keys,Object.values,Object.entries,for...inand object spread start returning the numeric keys too. An app that builds a list of statuses fromObject.values(codePush.SyncStatus)silently gets the names mixed in. The change shows up only at runtime.switch, passing members as options, and annotations likelet s: codePush.SyncStatuskeep compiling. Code that uses a member as a type, such aslet s: codePush.SyncStatus.UP_TO_DATE, has to change totypeof codePush.SyncStatus.UP_TO_DATE.Proposal
Change the typings in the next major release. Of the options, it is the only one whose breakage surfaces at compile time instead of changing behavior quietly, and it leaves the runtime alone.
DeploymentStatusis a string enum, which TypeScript never reverse-maps, so it is not affected.