MomentJS has a unique behavior when it comes to accepting input types. It will accept almost anything, and if the input is not what it expects, it converts it to a string implicitly. This can result in a Moment instance with a time value of NaN
, which you can check using the isValid()
method. More details on this are provided below.
Regarding the general question at hand, it is unfortunately not possible to dynamically discover and test for all the types used by MomentJS in its MomentInput
type at runtime.
The current definition of the MomentInput
type includes:
type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | null | undefined;
You could potentially create a type predicate to determine if a given value matches any of these types. However, it may be complicated due to the optional nature of MomentInputObject
, where all 24 properties are optional.
Despite the complexities, an attempt can still be made as shown below:
// Note: This example code is untested and may require adjustments based on specific use cases.
import moment, { isMoment, MomentInput, MomentInputObject } from "moment";
function isMomentInput(value: any): value is MomentInput {
switch (typeof value) {
case "string":
case "number":
case "undefined":
return true;
case "object":
if (value instanceof Date) {
return true;
}
if (Array.isArray(value)) {
return value.every((element) => {
const elementType = typeof element;
return elementType === "string" || elementType === "number";
});
}
return (
value === null || isMoment(moment) || isMomentInputObject(value)
);
}
return false;
}
const momentInputObjectPropNames = [
"years",
"year",
"y",
"months",
"month",
"M",
"days",
"day",
"d",
// Additional property names...
];
function isMomentInputObject(value: any): value is MomentInputObject {
return momentInputObjectPropNames.some((propName) => propName in value);
}
Subsequently, your code implementation would look like this:
someFunction(obj: any): Moment {
if (!isMomentInput(obj)) {
// Handling invalid Moment input scenario
}
return moment(obj);
}
It's important to note that the isMomentInput
function may need updates if there are changes to the MomentInput
definition in future versions of MomentJS. While MomentJS is currently in maintenance mode, it's worth considering for future compatibility.
Note: Remember to handle scenarios where the moment
call throws an error or returns a Moment instance with a time value of NaN
. Ensuring validity checks, as demonstrated in the sample code snippet, will help manage such situations effectively.
¹ Regarding potential errors thrown by moment
: Though uncommon, passing unsupported types like Symbol
could lead to errors. Objects that fail during implicit conversion to strings might also cause exceptions. Careful consideration of inputs is crucial to prevent such issues.