I'm currently facing a challenge with type unions and aliases. I have an alias for values that can possibly be null or undefined, along with a function that handles these values.
Everything is running smoothly and safely. However, there are instances where a safe value, which cannot be null or undefined, gets passed to the function due to oversights. Although this doesn't cause any issues because the function expects safe values as well, Typescript fails to raise a complaint.
The code snippet appears like this:
type Maybe<T> = T | null | undefined;
function handleDangerousValue<T>(val: Maybe<T>): T {
// Check stuff
return val as unknown as T;
}
const safeValue: number = 1;
const unsafeValue: Maybe<number> = null;
// Ideally, should generate a type error here
handleDangerousValue(safeValue);
// This is acceptable
handleDangerousValue(unsafeValue);
I wish to receive a notification from Typescript indicating that safeValue
does not possess the correct type.
I understand that the issue stems from how the union type is defined, but I am uncertain about how to resolve it. One possible solution could involve transforming DangerousValue<T>
into a class, but I prefer retaining it as a type to avoid additional complexity in resolving a typing dilemma.
edit:
After some experimentation, I made progress:
type Maybe<T> = T | null | undefined;
type EnforceMaybe<T> = Maybe<T> extends T ? Maybe<T> : never;
function handleDangerousValue<T>(val: EnforceMaybe<T>): T {
// Check stuff
return val as unknown as T;
}
const safeValue: number = 1;
const unsafeValue: Maybe<number> = null as Maybe<number>;
// Properly detects the issue
const n1: number = handleDangerousValue(safeValue);
// Now assumes that the return type should be a Maybe
const n2: number = handleDangerousValue(unsafeValue);
At this point, non-null values are restricted, yet Typescript struggles to infer the inner type of Maybe
.
Is there a way to deduce the return type based on this?