luxon
luxon copied to clipboard
Add constructors to DateTime and other classes
Is your feature request related to a problem? Please describe. I find it confusing that the constructors of DateTime and other classes (e.g. Interval, etc.) are default constructors (i.e. do nothing) and all fields do not have defaults, thereby meaning that the constructors construct essentially invalid objects, specifically:
const dateTime = new DateTime()
fails with TypeError: Cannot read property 'zone' of undefined
Describe the solution you'd like
Since the constructor fails, it would be sensible to implement it to do the same as DateTime.now(). This would give the same functionality as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#syntax which would simplify migration to Luxon
Describe alternatives you've considered
If returning the current datetime is not preferred, an alternative implementation could be to return DateTime.fromMillis(0) to return the epoch
An easier alternative to implementing the constructor would be to make them protected, such that the only way to construct it would be via the static methods or in a derived class.
Additional context
The failing constructor was observed with "@types/luxon" "1.25.0"
Same problem when trying to extend e.g. Interval, where it requires to call super(). Typescript thinks it takes no argument, when in fact the source says it does - probably bc. constructor is marked as private?
The constructor is meant to be private (e.g. as here). Unfortunately, as far as I know, there's no way to enforce this in the actual Javascript. The TypeScript types can, though, and they should. I just don't control them. I recommend filing a bug there.
We could of course support an empty constructor directly. I'm hesitant here: more code to check the args (because it's private, it doesn't), more stuff to document, more ways to do the same thing, etc. Can you make a fuller case for this?
Thanks for the response. I have trouble installing luxon in both stackblitz and plunkr - is there a working template?
I would also like to extend certain classes but Typescript complains due to the private constructors. My use case is adding a computed ID to an Interval to quickly identify two equal intervals. By use of:
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unreachable code error
I can still get this to work:
export class UniqueInterval extends Interval {
// Mark: Static Methods
public static fromInterval(interval: Interval): UniqueInterval {
return new UniqueInterval({
start: interval.start,
end: interval.end,
invalid: {
reason: interval.invalidReason,
explanation: interval.invalidExplanation,
},
});
}
// Mark: Properties
public get id(): string {
return getID(this);
}
// Mark: Initialization
// https://github.com/moment/luxon/issues/900
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(config: IntervalConfig) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unreachable code error
super(config);
}
}
@icambron the current version of the docs includes the line new DateTime(config: any) but there is no description. I'm not sure why, because the constructor is decorated @access private. It might be nice to mention this explicitly in the relevant docs, something like "The DateTime constructor is private, instead of constructing a new DateTime, call one of these methods: ...", etc.
ETA: the PR I just opened at DefinitelyTyped will correct the TS typings by marking the constructor as private.
@thw0rted yeah, our new doc processor doesn't seem to respect the private flag at least as I have written now. I'd prefer to just fix that so that the constructor disappears from the docs.
In case it helps I noticed that one of the constructors is @access private while others are @private -- I think the former is supposed to be a synonym for the latter, but maybe your processor only understands one of them?
@thw0rted some context here is that we changed doc processors, and probably just haven't tracked down all the stuff that works differently. This may be one of those