js-temporal/temporal-polyfill

Avoid exposing BigInt compatibility library implementation as part of public API when native BigInt is not available

Opened this issue · 1 comments

get epochSeconds() {
if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver');
const value = GetSlot(this, EPOCHNANOSECONDS);
return +value.divide(1e9);
}
get epochMilliseconds() {
if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver');
const value = bigInt(GetSlot(this, EPOCHNANOSECONDS));
return +value.divide(1e6);
}
get epochMicroseconds() {
if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver');
const value = GetSlot(this, EPOCHNANOSECONDS);
return bigIntIfAvailable(value.divide(1e3));
}
get epochNanoseconds() {
if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver');
return bigIntIfAvailable(GetSlot(this, EPOCHNANOSECONDS));
}

In some places, Temporal specifies it returns bigint, the native BigInt type. This polyfill does aim to work on browsers that don't have native BigInt support (primarily, IE11), but returning the objects used by a BigInt compatibility library can cause maintenance headaches for both us as maintainers and our consumers (who would likely have to update their code if we ever changed or removed the BigInt compatibility layer). This issue tracks how we handle this problem.

Quoting @ptomato:

other options would be to return numbers, or strings, or omit entry points that accept or return bigints

It would be interesting to explore omitting these properties when we know that BigInt is not available, maybe something like (untested) static fromEpochMicroseconds(epochMicroseconds: BigInt ? bigint : never): Temporal.Instant;

I think w.r.t. the runtime behaviour, returning string base-10 representations of the numbers when native bigint is not available seems reasonable to me (as that is definitely compatible with other bigint support libraries).

r.e. types:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#bigint

Due to needing to adjust the support level for tsc to even "see" the bigint type, I don't know how feasible it is to provide this sort of conditional type (something like this, which doesn't seem to work: type BigIntIfAvailable = BigInt extends never ? string : bigint).