Refactor to enforce strictNullChecks
This commit applies `strictNullChecks` to the entire codebase to improve maintainability and type safety. Key changes include: - Remove some explicit null-checks where unnecessary. - Add necessary null-checks. - Refactor static factory functions for a more functional approach. - Improve some test names and contexts for better debugging. - Add unit tests for any additional logic introduced. - Refactor `createPositionFromRegexFullMatch` to its own function as the logic is reused. - Prefer `find` prefix on functions that may return `undefined` and `get` prefix for those that always return a value.
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
import { IApplication } from '@/domain/IApplication';
|
||||
|
||||
export function useApplication(application: IApplication) {
|
||||
if (!application) {
|
||||
throw new Error('missing application');
|
||||
}
|
||||
return {
|
||||
application,
|
||||
info: application.info,
|
||||
|
||||
@@ -7,13 +7,6 @@ export function useCollectionState(
|
||||
context: IApplicationContext,
|
||||
events: IEventSubscriptionCollection,
|
||||
) {
|
||||
if (!context) {
|
||||
throw new Error('missing context');
|
||||
}
|
||||
if (!events) {
|
||||
throw new Error('missing events');
|
||||
}
|
||||
|
||||
const currentState = shallowRef<IReadOnlyCategoryCollectionState>(context.state);
|
||||
events.register([
|
||||
context.contextChanged.on((event) => {
|
||||
@@ -28,9 +21,6 @@ export function useCollectionState(
|
||||
handler: NewStateEventHandler,
|
||||
settings: Partial<IStateCallbackSettings> = defaultSettings,
|
||||
) {
|
||||
if (!handler) {
|
||||
throw new Error('missing state handler');
|
||||
}
|
||||
events.register([
|
||||
context.contextChanged.on((event) => {
|
||||
handler(event.newState, event.oldState);
|
||||
@@ -46,16 +36,10 @@ export function useCollectionState(
|
||||
}
|
||||
|
||||
function modifyCurrentState(mutator: StateModifier) {
|
||||
if (!mutator) {
|
||||
throw new Error('missing state mutator');
|
||||
}
|
||||
mutator(context.state);
|
||||
}
|
||||
|
||||
function modifyCurrentContext(mutator: ContextModifier) {
|
||||
if (!mutator) {
|
||||
throw new Error('missing context mutator');
|
||||
}
|
||||
mutator(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { IRuntimeEnvironment } from '@/infrastructure/RuntimeEnvironment/IRuntimeEnvironment';
|
||||
|
||||
export function useRuntimeEnvironment(environment: IRuntimeEnvironment) {
|
||||
if (!environment) {
|
||||
throw new Error('missing environment');
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ const RawSvgLoaders = import.meta.glob('@/presentation/assets/icons/**/*.svg', {
|
||||
});
|
||||
|
||||
function modifySvg(svgSource: string): string {
|
||||
const parser = new window.DOMParser();
|
||||
const parser = new globalThis.window.DOMParser();
|
||||
const doc = parser.parseFromString(svgSource, 'image/svg+xml');
|
||||
let svgRoot = doc.documentElement;
|
||||
svgRoot = removeSvgComments(svgRoot);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Ref, watchEffect } from 'vue';
|
||||
* Manages focus transitions, ensuring good usability and accessibility.
|
||||
*/
|
||||
export function useCurrentFocusToggle(shouldDisableFocus: Ref<boolean>) {
|
||||
let previouslyFocusedElement: HTMLElement | undefined;
|
||||
let previouslyFocusedElement: HTMLElement | null;
|
||||
|
||||
watchEffect(() => {
|
||||
if (shouldDisableFocus.value) {
|
||||
@@ -17,7 +17,7 @@ export function useCurrentFocusToggle(shouldDisableFocus: Ref<boolean>) {
|
||||
return;
|
||||
}
|
||||
previouslyFocusedElement.focus();
|
||||
previouslyFocusedElement = undefined;
|
||||
previouslyFocusedElement = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
defineComponent, shallowRef, onMounted, onBeforeUnmount,
|
||||
defineComponent, shallowRef, onMounted, onBeforeUnmount, watch,
|
||||
} from 'vue';
|
||||
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/UseResizeObserverPolyfill';
|
||||
|
||||
@@ -25,61 +25,63 @@ export default defineComponent({
|
||||
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
let observer: ResizeObserver;
|
||||
let observer: ResizeObserver | undefined;
|
||||
|
||||
onMounted(() => {
|
||||
width = containerElement.value.offsetWidth;
|
||||
height = containerElement.value.offsetHeight;
|
||||
|
||||
resizeObserverReady.then(() => {
|
||||
observer = new ResizeObserver(updateSize);
|
||||
observer.observe(containerElement.value);
|
||||
});
|
||||
|
||||
fireChangeEvents();
|
||||
watch(() => containerElement.value, async (element) => {
|
||||
if (!element) {
|
||||
disposeObserver();
|
||||
return;
|
||||
}
|
||||
resizeObserverReady.then(() => {
|
||||
observer = new ResizeObserver(updateSize);
|
||||
observer.observe(element);
|
||||
});
|
||||
updateSize();
|
||||
}, { immediate: true });
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
observer?.disconnect();
|
||||
disposeObserver();
|
||||
});
|
||||
|
||||
function updateSize() {
|
||||
let sizeChanged = false;
|
||||
if (isWidthChanged()) {
|
||||
updateWidth(containerElement.value.offsetWidth);
|
||||
sizeChanged = true;
|
||||
}
|
||||
if (isHeightChanged()) {
|
||||
updateHeight(containerElement.value.offsetHeight);
|
||||
sizeChanged = true;
|
||||
}
|
||||
if (sizeChanged) {
|
||||
const changes = [
|
||||
updateWidth(),
|
||||
updateHeight(),
|
||||
];
|
||||
if (changes.some((c) => c.isChanged)) {
|
||||
emit('sizeChanged');
|
||||
}
|
||||
}
|
||||
|
||||
function updateWidth(newWidth: number) {
|
||||
function updateWidth(): {
|
||||
readonly isChanged: boolean;
|
||||
} {
|
||||
const newWidth = containerElement.value?.offsetWidth ?? 0;
|
||||
if (newWidth === width) {
|
||||
return { isChanged: false };
|
||||
}
|
||||
width = newWidth;
|
||||
emit('widthChanged', newWidth);
|
||||
return { isChanged: true };
|
||||
}
|
||||
|
||||
function updateHeight(newHeight: number) {
|
||||
function updateHeight(): {
|
||||
readonly isChanged: boolean;
|
||||
} {
|
||||
const newHeight = containerElement.value?.offsetHeight ?? 0;
|
||||
if (newHeight === height) {
|
||||
return { isChanged: false };
|
||||
}
|
||||
height = newHeight;
|
||||
emit('heightChanged', newHeight);
|
||||
return { isChanged: true };
|
||||
}
|
||||
|
||||
function fireChangeEvents() {
|
||||
updateWidth(containerElement.value.offsetWidth);
|
||||
updateHeight(containerElement.value.offsetHeight);
|
||||
emit('sizeChanged');
|
||||
}
|
||||
|
||||
function isWidthChanged(): boolean {
|
||||
return width !== containerElement.value.offsetWidth;
|
||||
}
|
||||
|
||||
function isHeightChanged(): boolean {
|
||||
return height !== containerElement.value.offsetHeight;
|
||||
function disposeObserver() {
|
||||
observer?.disconnect();
|
||||
observer = undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -10,11 +10,11 @@ export function throttle(
|
||||
}
|
||||
|
||||
// Allows aligning with both NodeJs (NodeJs.Timeout) and Window type (number)
|
||||
export type TimeoutType = ReturnType<typeof setTimeout>;
|
||||
export type Timeout = ReturnType<typeof setTimeout>;
|
||||
|
||||
export interface ITimer {
|
||||
setTimeout: (callback: () => void, ms: number) => TimeoutType;
|
||||
clearTimeout: (timeoutId: TimeoutType) => void;
|
||||
setTimeout: (callback: () => void, ms: number) => Timeout;
|
||||
clearTimeout: (timeoutId: Timeout) => void;
|
||||
dateNow(): number;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ interface IThrottler {
|
||||
}
|
||||
|
||||
class Throttler implements IThrottler {
|
||||
private queuedExecutionId: TimeoutType;
|
||||
private queuedExecutionId: Timeout | undefined;
|
||||
|
||||
private previouslyRun: number;
|
||||
|
||||
@@ -38,10 +38,8 @@ class Throttler implements IThrottler {
|
||||
private readonly waitInMs: number,
|
||||
private readonly callback: CallbackType,
|
||||
) {
|
||||
if (!timer) { throw new Error('missing timer'); }
|
||||
if (!waitInMs) { throw new Error('missing delay'); }
|
||||
if (waitInMs < 0) { throw new Error('negative delay'); }
|
||||
if (!callback) { throw new Error('missing callback'); }
|
||||
}
|
||||
|
||||
public invoke(...args: unknown[]): void {
|
||||
|
||||
Reference in New Issue
Block a user