microsoft / microsoft/vscode-react-native
[Feature] Improve type safety by reducing 'any' type usage in CDP message handlers
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 295
- Avg merge
- 11h 17m
- Merged PRs (30d)
- 24
Description
Summary
The CDP (Chrome DevTools Protocol) message handler files use any type extensively, reducing type safety and making the code harder to maintain and debug.
Current Situation
High usage of any type in CDP handlers:
src/cdp-proxy/CDPMessageHandlers/hermesCDPMessageHandler.ts:
- processDebuggerCDPMessage(event: any)
- processApplicationCDPMessage(event: any)
- handleCallFunctionOnEvent(event: any): any
- handleFunctionTypeResult(event: any): any
- handlePausedEvent(event: any): any
- handleBreakpointSetting(event: any): any
src/cdp-proxy/CDPMessageHandlers/iOSDirectCDPMessageHandler.ts:
- processDebuggerCDPMessage(event: any)
- processApplicationCDPMessage(event: any)
- processDeprecatedConsoleMessage(event: any)
- params: any = {}
src/cdp-proxy/CDPMessageHandlers/rnCDPMessageHandler.ts:
- processDebuggerCDPMessage(event: any)
- processApplicationCDPMessage(event: any)
- handleAppBundleFirstPauseEvent(event: IProtocolCommand): any
- params: any = event.params
Interface definition:
interface ICDPMessageHandler {
processDebuggerCDPMessage: (event: any) => ProcessedCDPMessage;
processApplicationCDPMessage: (event: any) => ProcessedCDPMessage;
}
Problems with Current Approach
- No compile-time type checking: Can't catch CDP message structure errors at build time
- Poor IntelliSense: No autocomplete for CDP message properties
- Runtime errors: Easy to access non-existent properties without warning
- Maintainability: Harder to understand expected message structure
- Refactoring risk: Changes can break code without TypeScript catching it
Proposed Changes
Phase 1: Define CDP Message Types
Create type definitions for CDP protocol messages:
// cdp-proxy/types/CDPMessages.ts
interface CDPEvent {
method: string;
params?: Record<string, unknown>;
}
interface CDPCallFunctionOnEvent extends CDPEvent {
method: 'Runtime.callFunctionOn';
params: {
functionDeclaration: string;
objectId?: string;
arguments?: any[];
returnByValue?: boolean;
};
}
interface CDPPausedEvent extends CDPEvent {
method: 'Debugger.paused';
params: {
callFrames: CallFrame[];
reason: string;
data?: Record<string, unknown>;
};
}
interface CallFrame {
callFrameId: string;
functionName: string;
location: Location;
scopeChain: Scope[];
}
// ... more type definitions
Phase 2: Update Handler Interfaces
Replace any with proper types:
interface ICDPMessageHandler {
processDebuggerCDPMessage: (event: CDPEvent) => ProcessedCDPMessage;
processApplicationCDPMessage: (event: CDPEvent) => ProcessedCDPMessage;
}
Phase 3: Add Type Guards
Implement type guards for runtime type checking:
function isCDPCallFunctionOnEvent(event: CDPEvent): event is CDPCallFunctionOnEvent {
return event.method === 'Runtime.callFunctionOn';
}
function isCDPPausedEvent(event: CDPEvent): event is CDPPausedEvent {
return event.method === 'Debugger.paused';
}
Phase 4: Update Handler Implementations
Use type guards in handlers:
public processDebuggerCDPMessage(event: CDPEvent): ProcessedCDPMessage {
if (isCDPCallFunctionOnEvent(event)) {
return this.handleCallFunctionOnEvent(event);
}
if (isCDPPausedEvent(event)) {
return this.handlePausedEvent(event);
}
// ...
}
private handleCallFunctionOnEvent(event: CDPCallFunctionOnEvent): ProcessedCDPMessage {
// event.params is now properly typed
const { functionDeclaration, objectId } = event.params;
// ...
}
Benefits
- Type safety: Catch CDP message structure errors at compile time
- Better IntelliSense: Autocomplete for CDP message properties
- Self-documenting: Types serve as documentation for CDP protocol usage
- Refactoring safety: TypeScript catches breaking changes
- Debugging: Easier to identify message structure issues
- Maintenance: Clearer code intent and expected structures
Implementation Strategy
- Start with commonly used CDP message types
- Add type definitions incrementally (one handler at a time)
- Use union types for messages with variants
- Leverage TypeScript's discriminated unions for type narrowing
- Consider using existing CDP protocol type definitions if available
Potential Challenges
- CDP protocol has many message types
- Some messages have dynamic/flexible structures
- Need to balance type safety with flexibility
- Requires understanding CDP protocol specification
Alternative Approaches
- Use
@types/chrome-devtools-protocol: Leverage existing type definitions - Generate types from protocol JSON: Use CDP protocol specification
- Gradual typing: Start with loose types, refine incrementally
- Unknown over any: Use
unknowninstead ofanyfor better safety
References
- CDP Message Handlers:
src/cdp-proxy/CDPMessageHandlers/ - Chrome DevTools Protocol: https://chromedevtools.github.io/devtools-protocol/
- Potential types package:
@types/chrome-devtools-protocol - TypeScript discriminated unions: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the handlers under src/cdp-proxy/CDPMessageHandlers/ and the ICDPMessageHandler interface, then check whether existing CDP protocol types are available. Define types incrementally for the listed message shapes, add guards where needed, and update the handlers so the identified any usages are replaced while preserving their processed messages and behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- developer-experience, devtools, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100