Remove unnecessary type assertions across codebase
Add oxlint-tsgolint and configure typescript/no-unnecessary-type-assertion to flag redundant `!` and `as Foo` casts. Type-aware mode is left off by default to keep `npm run lint` fast; the rule sits configured for when we turn type-aware on intentionally. Auto-fix removed ~283 redundant casts; two manual touch-ups: a real tsgolint false positive in split-container.tsx and a stale ChildProcess import after a double-cast collapsed.
This commit is contained in:
@@ -234,7 +234,7 @@ function buildFallbackAllProviderModels(
|
||||
map.set(
|
||||
provider,
|
||||
modelOptions.map((option) => ({
|
||||
provider: provider as AgentProvider,
|
||||
provider: provider,
|
||||
id: option.id,
|
||||
label: option.label,
|
||||
})),
|
||||
|
||||
@@ -461,7 +461,7 @@ export function BrowserPane({
|
||||
};
|
||||
const handleFaviconUpdated = (event: Event) => {
|
||||
const favicons = Array.isArray((event as Event & { favicons?: unknown[] }).favicons)
|
||||
? (((event as Event & { favicons?: string[] }).favicons as string[] | undefined) ?? [])
|
||||
? ((event as Event & { favicons?: string[] }).favicons ?? [])
|
||||
: [];
|
||||
updateBrowserRef.current(browserIdRef.current, { faviconUrl: favicons[0] ?? null });
|
||||
};
|
||||
|
||||
@@ -63,8 +63,8 @@ describe("combined model selector helpers", () => {
|
||||
}),
|
||||
]);
|
||||
|
||||
expect(matchesSearch(rows[0]!, "claude")).toBe(true);
|
||||
expect(matchesSearch(rows[1]!, "gpt-5.4")).toBe(true);
|
||||
expect(matchesSearch(rows[0], "claude")).toBe(true);
|
||||
expect(matchesSearch(rows[1], "gpt-5.4")).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps the selected trigger label model-only", () => {
|
||||
|
||||
@@ -622,7 +622,7 @@ export function CombinedModelSelector({
|
||||
const singleProviderView = useMemo<SelectorView | null>(() => {
|
||||
const providers = Array.from(allProviderModels.keys());
|
||||
if (providers.length !== 1) return null;
|
||||
const providerId = providers[0]!;
|
||||
const providerId = providers[0];
|
||||
const label = resolveProviderLabel(providerDefinitions, providerId);
|
||||
return { kind: "provider", providerId, providerLabel: label };
|
||||
}, [allProviderModels, providerDefinitions]);
|
||||
@@ -655,7 +655,7 @@ export function CombinedModelSelector({
|
||||
|
||||
const handleSelect = useCallback(
|
||||
(provider: string, modelId: string) => {
|
||||
onSelect(provider as AgentProvider, modelId);
|
||||
onSelect(provider, modelId);
|
||||
setIsOpen(false);
|
||||
setSearchQuery("");
|
||||
},
|
||||
|
||||
@@ -160,20 +160,17 @@ function removeAttachmentAtIndex<T extends ComposerAttachment>(prev: T[], index:
|
||||
}
|
||||
|
||||
function buildCancelButtonStyle(isConnected: boolean, isCancellingAgent: boolean): object[] {
|
||||
const disabled =
|
||||
!isConnected || isCancellingAgent ? (styles.buttonDisabled as object) : undefined;
|
||||
return [styles.cancelButton as object, disabled].filter((value): value is object =>
|
||||
Boolean(value),
|
||||
);
|
||||
const disabled = !isConnected || isCancellingAgent ? styles.buttonDisabled : undefined;
|
||||
return [styles.cancelButton, disabled].filter((value): value is object => Boolean(value));
|
||||
}
|
||||
|
||||
function buildRealtimeVoiceButtonStyle(
|
||||
hovered: boolean | undefined,
|
||||
voiceButtonDisabled: boolean,
|
||||
): object[] {
|
||||
const hoveredStyle = hovered ? (styles.iconButtonHovered as object) : undefined;
|
||||
const disabledStyle = voiceButtonDisabled ? (styles.buttonDisabled as object) : undefined;
|
||||
return [styles.realtimeVoiceButton as object, hoveredStyle, disabledStyle].filter(
|
||||
const hoveredStyle = hovered ? styles.iconButtonHovered : undefined;
|
||||
const disabledStyle = voiceButtonDisabled ? styles.buttonDisabled : undefined;
|
||||
return [styles.realtimeVoiceButton, hoveredStyle, disabledStyle].filter(
|
||||
(value): value is object => Boolean(value),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ function TreeRowItem({
|
||||
);
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
void onCopyPath(entry.path);
|
||||
onCopyPath(entry.path);
|
||||
}, [onCopyPath, entry.path]);
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
|
||||
@@ -29,7 +29,7 @@ interface PathRowProps {
|
||||
function PathRow({ path, active, onSelect }: PathRowProps) {
|
||||
const { theme } = useUnistyles();
|
||||
const handlePress = useCallback(() => {
|
||||
void onSelect(path);
|
||||
onSelect(path);
|
||||
}, [onSelect, path]);
|
||||
const pressableStyle = useCallback(
|
||||
({ hovered = false, pressed }: PressableStateCallbackType & { hovered?: boolean }) => [
|
||||
@@ -172,7 +172,7 @@ export function ProjectPickerModal() {
|
||||
if (key === "Enter") {
|
||||
event.preventDefault();
|
||||
if (options.length > 0 && activeIndex < options.length) {
|
||||
void handleSelectPath(options[activeIndex]!);
|
||||
void handleSelectPath(options[activeIndex]);
|
||||
} else if (query.trim()) {
|
||||
handleSubmitCustom();
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ function CustomModelsSection(props: {
|
||||
},
|
||||
},
|
||||
});
|
||||
await refresh([provider as AgentProvider]);
|
||||
await refresh([provider]);
|
||||
},
|
||||
[patchConfig, provider, refresh],
|
||||
);
|
||||
@@ -284,7 +284,7 @@ export function ProviderDiagnosticSheet({
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await client.getProviderDiagnostic(provider as AgentProvider);
|
||||
const result = await client.getProviderDiagnostic(provider);
|
||||
setDiagnostic(result.diagnostic);
|
||||
} catch (err) {
|
||||
setDiagnostic(err instanceof Error ? err.message : "Failed to fetch diagnostic");
|
||||
@@ -308,7 +308,7 @@ export function ProviderDiagnosticSheet({
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
void Promise.all([refresh([provider as AgentProvider]), fetchDiagnostic()]).catch((err) => {
|
||||
void Promise.all([refresh([provider]), fetchDiagnostic()]).catch((err) => {
|
||||
setDiagnostic(err instanceof Error ? err.message : "Failed to refresh provider");
|
||||
});
|
||||
}, [fetchDiagnostic, provider, refresh]);
|
||||
|
||||
@@ -351,7 +351,7 @@ describe("sidebar workspace render isolation", () => {
|
||||
act(() => {
|
||||
useSessionStore.getState().mergeWorkspaces(SERVER_ID, [
|
||||
{
|
||||
...createWorkspaces()[1]!,
|
||||
...createWorkspaces()[1],
|
||||
status: "running",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -439,7 +439,7 @@ function WorkspaceStatusIndicator({
|
||||
);
|
||||
}
|
||||
|
||||
let KindIcon: typeof ThemedMonitor | typeof ThemedFolderGit2 | null;
|
||||
let KindIcon: typeof ThemedMonitor | null;
|
||||
if (workspaceKind === "local_checkout") KindIcon = ThemedMonitor;
|
||||
else if (workspaceKind === "worktree") KindIcon = ThemedFolderGit2;
|
||||
else KindIcon = null;
|
||||
|
||||
@@ -488,7 +488,7 @@ function handleDesktopEnterKey(input: DesktopKeyHandlerInput) {
|
||||
if (input.orderedVisibleOptions.length === 0) return;
|
||||
const { activeIndex, orderedVisibleOptions } = input;
|
||||
const index = activeIndex >= 0 && activeIndex < orderedVisibleOptions.length ? activeIndex : 0;
|
||||
input.handleSelect(orderedVisibleOptions[index]!.id);
|
||||
input.handleSelect(orderedVisibleOptions[index].id);
|
||||
}
|
||||
|
||||
interface FloatingSizeSetters {
|
||||
|
||||
@@ -140,9 +140,9 @@ export function useWebScrollViewScrollbar(
|
||||
const scrollable = scrollableRef.current;
|
||||
if (!scrollable) return;
|
||||
if ("scrollToOffset" in scrollable) {
|
||||
(scrollable as FlatList).scrollToOffset({ offset, animated: false });
|
||||
scrollable.scrollToOffset({ offset, animated: false });
|
||||
} else {
|
||||
(scrollable as ScrollView).scrollTo({ y: offset, animated: false });
|
||||
scrollable.scrollTo({ y: offset, animated: false });
|
||||
}
|
||||
},
|
||||
[scrollableRef],
|
||||
|
||||
Reference in New Issue
Block a user