fix: resolve all TypeScript strict null check errors

Fix ~68 pre-existing strict null errors across 13 feature modules.
Add non-null assertions for DOM element lookups, null coalescing for
optional values, and type guards for nullable properties. Zero tsc
errors now with --noEmit.
This commit is contained in:
2026-03-24 13:59:07 +03:00
parent c0d0d839dc
commit 1111ab7355
13 changed files with 85 additions and 75 deletions

View File

@@ -191,11 +191,11 @@ function renderAutomations(automations: any, sceneMap: any) {
{ key: 'scenes', html: csScenes.render(sceneItems) },
].map(p => `<div class="automation-sub-tab-panel stream-tab-panel${p.key === activeTab ? ' active' : ''}" id="automation-tab-${p.key}">${p.html}</div>`).join('');
container.innerHTML = panels;
container!.innerHTML = panels;
CardSection.bindAll([csAutomations, csScenes]);
// Event delegation for scene preset card actions
initScenePresetDelegation(container);
initScenePresetDelegation(container!);
_automationsTree.setExtraHtml(`<button class="tutorial-trigger-btn" onclick="startAutomationsTutorial()" data-i18n-title="tour.restart" title="${t('tour.restart')}">${ICON_HELP}</button>`);
_automationsTree.update(treeItems, activeTab);
@@ -313,7 +313,7 @@ export async function openAutomationEditor(automationId?: any, cloneData?: any)
const errorEl = document.getElementById('automation-editor-error') as HTMLElement;
errorEl.style.display = 'none';
condList.innerHTML = '';
condList!.innerHTML = '';
_ensureConditionLogicIconSelect();
_ensureDeactivationModeIconSelect();
@@ -331,7 +331,7 @@ export async function openAutomationEditor(automationId?: any, cloneData?: any)
let _editorTags: any[] = [];
if (automationId) {
titleEl.innerHTML = `${ICON_AUTOMATION} ${t('automations.edit')}`;
titleEl!.innerHTML = `${ICON_AUTOMATION} ${t('automations.edit')}`;
try {
const resp = await fetchWithAuth(`/automations/${automationId}`);
if (!resp.ok) throw new Error('Failed to load automation');
@@ -363,7 +363,7 @@ export async function openAutomationEditor(automationId?: any, cloneData?: any)
}
} else if (cloneData) {
// Clone mode — create with prefilled data
titleEl.innerHTML = `${ICON_AUTOMATION} ${t('automations.add')}`;
titleEl!.innerHTML = `${ICON_AUTOMATION} ${t('automations.add')}`;
idInput.value = '';
nameInput.value = (cloneData.name || '') + ' (Copy)';
enabledInput.checked = cloneData.enabled !== false;
@@ -386,7 +386,7 @@ export async function openAutomationEditor(automationId?: any, cloneData?: any)
_initSceneSelector('automation-fallback-scene-id', cloneData.deactivation_scene_preset_id);
_editorTags = cloneData.tags || [];
} else {
titleEl.innerHTML = `${ICON_AUTOMATION} ${t('automations.add')}`;
titleEl!.innerHTML = `${ICON_AUTOMATION} ${t('automations.add')}`;
idInput.value = '';
nameInput.value = '';
enabledInput.checked = true;
@@ -400,11 +400,11 @@ export async function openAutomationEditor(automationId?: any, cloneData?: any)
(document.getElementById('automation-deactivation-mode') as HTMLSelectElement).onchange = _onDeactivationModeChange;
automationModal.open();
modal.querySelectorAll('[data-i18n]').forEach(el => {
el.textContent = t(el.getAttribute('data-i18n'));
modal!.querySelectorAll('[data-i18n]').forEach(el => {
el.textContent = t(el.getAttribute('data-i18n')!);
});
modal.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
(el as HTMLInputElement).placeholder = t(el.getAttribute('data-i18n-placeholder'));
modal!.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
(el as HTMLInputElement).placeholder = t(el.getAttribute('data-i18n-placeholder')!);
});
// Tags
@@ -762,7 +762,7 @@ function addAutomationConditionRow(condition: any) {
renderFields(typeSelect.value, {});
});
list.appendChild(row);
list!.appendChild(row);
}