Reputation: 59485
I am curious if it is possible to have one getOrFail
function that does what I have below. As you can see the contents of both functions are the same, but the argument types are different.
export const getStringOrFail = (value: string | null, message: string = 'getStringOrFail error'): string => {
if (value !== null) return value
throw new Error(message);
}
export const getNumberOrFail = (value: number | null, message: string = 'getNumberOrFail error'): number => {
if (value !== null) return value
throw new Error(message);
}
I tried using a generic and returning that but then it's possible to return null
.
How can I define one function that does what I have above?
Upvotes: 0
Views: 687
Reputation: 153030
What you'll want to do is define a generic parameter, which doesn't include null
:
export const getOrFail = <T extends string | number>(value: T | null, message: string = 'getOrFail error'): T => {
if (value !== null) return value
throw new Error(message);
}
As @jcalz suggested, if you want to go more generic and allow everything except null
. You can use {} | undefined | void
instead of string | number
:
export const getOrFail = <T extends {} | undefined | void>(value: T | null, message: string = 'getOrFail error'): T => {
if (value !== null) return value
throw new Error(message);
}
Upvotes: 2
Reputation: 329533
Just to note another approach for completeness (it's not necessarily better than any of the others), using a conditional return type that Exclude
s null
:
export const getOrFail = <T>(
value: T | null,
message: string = "getOrFail error"
) => {
if (value !== null) return value as Exclude<T, null>;
throw new Error(message);
};
And check how it behaves:
const bool = getOrFail(true); // boolean
const nevr = getOrFail(null); // never
const undef = getOrFail(undefined); // undefined
const strng = getOrFail(Math.random() < 0.5 ? "hello" : null); // string
That last one has a parameter of type string | null
and the return type is Exclude<string | null, null>
, or just string
.
Upvotes: 1
Reputation: 977
Try generic, but T
should extend {}
.
export function getOrFail<T extends {}>(value: T | null | undefined, message: string = "getNumberOrFail error"): T {
if (value != null) return value;
throw new Error(message);
}
{}
allows everything except null or undefined.
More info here.
Upvotes: 2