@@ -18,6 +18,7 @@ const ReflectApply = Reflect.apply;
18
18
import { DEBUG } from './debug' ;
19
19
import bigInt from 'big-integer' ;
20
20
21
+ import type { Temporal } from '..' ;
21
22
import { GetIntrinsic } from './intrinsicclass' ;
22
23
import {
23
24
CreateSlots ,
@@ -68,25 +69,14 @@ function IsInteger(value: unknown): value is number {
68
69
return MathFloor ( abs ) === abs ;
69
70
}
70
71
71
- export function Type ( value : unknown ) : string {
72
- if ( value === null ) return 'Null' ;
73
- switch ( typeof value ) {
74
- case 'symbol' :
75
- return 'Symbol' ;
76
- case 'bigint' :
77
- return 'BigInt' ;
78
- case 'undefined' :
79
- return 'undefined' ;
80
- case 'function' :
81
- case 'object' :
82
- return 'Object' ;
83
- case 'number' :
84
- return 'Number' ;
85
- case 'boolean' :
86
- return 'Boolean' ;
87
- case 'string' :
88
- return 'String' ;
89
- }
72
+ // For unknown values, this narrows the result to a Record. But for union types
73
+ // like `Temporal.DurationLike | string`, it'll strip the primitive types while
74
+ // leaving the object type(s) unchanged.
75
+ export function IsObject < T > (
76
+ value : T
77
+ ) : value is Exclude < T , string | null | undefined | number | bigint | symbol | boolean > ;
78
+ export function IsObject ( value : unknown ) : value is Record < string | number | symbol , unknown > {
79
+ return ( typeof value === 'object' && value !== null ) || typeof value === 'function' ;
90
80
}
91
81
92
82
export function ToNumber ( value : unknown ) : number {
@@ -109,16 +99,16 @@ export function ToString(value: unknown): string {
109
99
return String ( value ) ;
110
100
}
111
101
112
- export function ToIntegerThrowOnInfinity ( value ) {
102
+ export function ToIntegerThrowOnInfinity ( value ) : number {
113
103
const integer = ToInteger ( value ) ;
114
104
if ( ! NumberIsFinite ( integer ) ) {
115
105
throw new RangeError ( 'infinity is out of range' ) ;
116
106
}
117
107
return integer ;
118
108
}
119
109
120
- export function ToPositiveInteger ( value , property ?: string ) {
121
- value = ToInteger ( value ) ;
110
+ export function ToPositiveInteger ( valueParam : unknown , property ?: string ) : number {
111
+ const value = ToInteger ( valueParam ) ;
122
112
if ( ! NumberIsFinite ( value ) ) {
123
113
throw new RangeError ( 'infinity is out of range' ) ;
124
114
}
@@ -131,15 +121,15 @@ export function ToPositiveInteger(value, property?: string) {
131
121
return value ;
132
122
}
133
123
134
- function ToIntegerNoFraction ( value ) {
135
- value = ToNumber ( value ) ;
124
+ function ToIntegerNoFraction ( valueParam : unknown ) : number {
125
+ const value = ToNumber ( valueParam ) ;
136
126
if ( ! IsInteger ( value ) ) {
137
127
throw new RangeError ( `unsupported fractional value ${ value } ` ) ;
138
128
}
139
129
return value ;
140
130
}
141
131
142
- const BUILTIN_CASTS = new Map ( [
132
+ const BUILTIN_CASTS = new Map < string , ( v : unknown ) => number | string > ( [
143
133
[ 'year' , ToIntegerThrowOnInfinity ] ,
144
134
[ 'month' , ToPositiveInteger ] ,
145
135
[ 'monthCode' , ToString ] ,
@@ -213,29 +203,29 @@ function getIntlDateTimeFormatEnUsForTimeZone(timeZoneIdentifier) {
213
203
return instance ;
214
204
}
215
205
216
- export function IsTemporalInstant ( item ) {
206
+ export function IsTemporalInstant ( item : unknown ) : item is Temporal . Instant {
217
207
return HasSlot ( item , EPOCHNANOSECONDS ) && ! HasSlot ( item , TIME_ZONE , CALENDAR ) ;
218
208
}
219
209
220
- export function IsTemporalTimeZone ( item ) {
210
+ export function IsTemporalTimeZone ( item : unknown ) : item is Temporal . TimeZone {
221
211
return HasSlot ( item , TIMEZONE_ID ) ;
222
212
}
223
- export function IsTemporalCalendar ( item ) {
213
+ export function IsTemporalCalendar ( item : unknown ) : item is Temporal . Calendar {
224
214
return HasSlot ( item , CALENDAR_ID ) ;
225
215
}
226
- export function IsTemporalDuration ( item ) {
216
+ export function IsTemporalDuration ( item : unknown ) : item is Temporal . Duration {
227
217
return HasSlot ( item , YEARS , MONTHS , DAYS , HOURS , MINUTES , SECONDS , MILLISECONDS , MICROSECONDS , NANOSECONDS ) ;
228
218
}
229
- export function IsTemporalDate ( item ) {
219
+ export function IsTemporalDate ( item : unknown ) : item is Temporal . PlainDate {
230
220
return HasSlot ( item , DATE_BRAND ) ;
231
221
}
232
- export function IsTemporalTime ( item ) {
222
+ export function IsTemporalTime ( item : unknown ) : item is Temporal . PlainTime {
233
223
return (
234
224
HasSlot ( item , ISO_HOUR , ISO_MINUTE , ISO_SECOND , ISO_MILLISECOND , ISO_MICROSECOND , ISO_NANOSECOND ) &&
235
225
! HasSlot ( item , ISO_YEAR , ISO_MONTH , ISO_DAY )
236
226
) ;
237
227
}
238
- export function IsTemporalDateTime ( item ) {
228
+ export function IsTemporalDateTime ( item : unknown ) : item is Temporal . PlainDateTime {
239
229
return HasSlot (
240
230
item ,
241
231
ISO_YEAR ,
@@ -249,13 +239,13 @@ export function IsTemporalDateTime(item) {
249
239
ISO_NANOSECOND
250
240
) ;
251
241
}
252
- export function IsTemporalYearMonth ( item ) {
242
+ export function IsTemporalYearMonth ( item : unknown ) : item is Temporal . PlainYearMonth {
253
243
return HasSlot ( item , YEAR_MONTH_BRAND ) ;
254
244
}
255
- export function IsTemporalMonthDay ( item ) {
245
+ export function IsTemporalMonthDay ( item : unknown ) : item is Temporal . PlainMonthDay {
256
246
return HasSlot ( item , MONTH_DAY_BRAND ) ;
257
247
}
258
- export function IsTemporalZonedDateTime ( item ) {
248
+ export function IsTemporalZonedDateTime ( item : unknown ) : item is Temporal . ZonedDateTime {
259
249
return HasSlot ( item , EPOCHNANOSECONDS , TIME_ZONE , CALENDAR ) ;
260
250
}
261
251
function TemporalTimeZoneFromString ( stringIdent ) {
@@ -606,7 +596,7 @@ function ToTemporalDurationRecord(item) {
606
596
607
597
export function ToLimitedTemporalDuration ( item , disallowedProperties = [ ] ) {
608
598
let record ;
609
- if ( Type ( item ) === 'Object' ) {
599
+ if ( IsObject ( item ) ) {
610
600
record = ToTemporalDurationRecord ( item ) ;
611
601
} else {
612
602
const str = ToString ( item ) ;
@@ -711,7 +701,7 @@ export function ToSecondsStringPrecision(options): {
711
701
}
712
702
let digits = options . fractionalSecondDigits ;
713
703
if ( digits === undefined ) digits = 'auto' ;
714
- if ( Type ( digits ) !== 'Number ' ) {
704
+ if ( typeof digits !== 'number ' ) {
715
705
digits = ToString ( digits ) ;
716
706
if ( digits === 'auto' ) return { precision : 'auto' , unit : 'nanosecond' , increment : 1 } ;
717
707
throw new RangeError ( `fractionalSecondDigits must be 'auto' or 0 through 9, not ${ digits } ` ) ;
@@ -780,7 +770,7 @@ export function ToRelativeTemporalObject(options) {
780
770
781
771
let offsetBehaviour = 'option' ;
782
772
let year , month , day , hour , minute , second , millisecond , microsecond , nanosecond , calendar , timeZone , offset ;
783
- if ( Type ( relativeTo ) === 'Object' ) {
773
+ if ( IsObject ( relativeTo ) ) {
784
774
if ( IsTemporalZonedDateTime ( relativeTo ) || IsTemporalDateTime ( relativeTo ) ) return relativeTo ;
785
775
if ( IsTemporalDate ( relativeTo ) ) {
786
776
return CreateTemporalDateTime (
@@ -889,7 +879,7 @@ export function LargerOfTwoTemporalUnits(unit1, unit2) {
889
879
}
890
880
891
881
export function ToPartialRecord ( bag , fields , callerCast ?: ( value : unknown ) => unknown ) {
892
- if ( Type ( bag ) !== 'Object' ) return false ;
882
+ if ( ! IsObject ( bag ) ) return false ;
893
883
let any ;
894
884
for ( const property of fields ) {
895
885
const value = bag [ property ] ;
@@ -908,7 +898,7 @@ export function ToPartialRecord(bag, fields, callerCast?: (value: unknown) => un
908
898
}
909
899
910
900
export function PrepareTemporalFields ( bag , fields ) {
911
- if ( Type ( bag ) !== 'Object' ) return undefined ;
901
+ if ( ! IsObject ( bag ) ) return undefined ;
912
902
const result = { } ;
913
903
let any = false ;
914
904
for ( const fieldRecord of fields ) {
@@ -1042,7 +1032,7 @@ export function ToTemporalZonedDateTimeFields(bag, fieldNames) {
1042
1032
}
1043
1033
1044
1034
export function ToTemporalDate ( item , options = ObjectCreate ( null ) ) {
1045
- if ( Type ( item ) === 'Object' ) {
1035
+ if ( IsObject ( item ) ) {
1046
1036
if ( IsTemporalDate ( item ) ) return item ;
1047
1037
if ( IsTemporalZonedDateTime ( item ) ) {
1048
1038
item = BuiltinTimeZoneGetPlainDateTimeFor (
@@ -1091,7 +1081,7 @@ export function InterpretTemporalDateTimeFields(calendar, fields, options) {
1091
1081
1092
1082
export function ToTemporalDateTime ( item , options = ObjectCreate ( null ) ) {
1093
1083
let year , month , day , hour , minute , second , millisecond , microsecond , nanosecond , calendar ;
1094
- if ( Type ( item ) === 'Object' ) {
1084
+ if ( IsObject ( item ) ) {
1095
1085
if ( IsTemporalDateTime ( item ) ) return item ;
1096
1086
if ( IsTemporalZonedDateTime ( item ) ) {
1097
1087
return BuiltinTimeZoneGetPlainDateTimeFor (
@@ -1147,7 +1137,7 @@ export function ToTemporalDateTime(item, options = ObjectCreate(null)) {
1147
1137
1148
1138
export function ToTemporalDuration ( item ) {
1149
1139
let years , months , weeks , days , hours , minutes , seconds , milliseconds , microseconds , nanoseconds ;
1150
- if ( Type ( item ) === 'Object' ) {
1140
+ if ( IsObject ( item ) ) {
1151
1141
if ( IsTemporalDuration ( item ) ) return item ;
1152
1142
( { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } =
1153
1143
ToTemporalDurationRecord ( item ) ) ;
@@ -1182,7 +1172,7 @@ export function ToTemporalInstant(item) {
1182
1172
}
1183
1173
1184
1174
export function ToTemporalMonthDay ( item , options = ObjectCreate ( null ) ) {
1185
- if ( Type ( item ) === 'Object' ) {
1175
+ if ( IsObject ( item ) ) {
1186
1176
if ( IsTemporalMonthDay ( item ) ) return item ;
1187
1177
let calendar , calendarAbsent ;
1188
1178
if ( HasSlot ( item , CALENDAR ) ) {
@@ -1221,7 +1211,7 @@ export function ToTemporalMonthDay(item, options = ObjectCreate(null)) {
1221
1211
1222
1212
export function ToTemporalTime ( item , overflow = 'constrain' ) {
1223
1213
let hour , minute , second , millisecond , microsecond , nanosecond , calendar ;
1224
- if ( Type ( item ) === 'Object' ) {
1214
+ if ( IsObject ( item ) ) {
1225
1215
if ( IsTemporalTime ( item ) ) return item ;
1226
1216
if ( IsTemporalZonedDateTime ( item ) ) {
1227
1217
item = BuiltinTimeZoneGetPlainDateTimeFor (
@@ -1269,7 +1259,7 @@ export function ToTemporalTime(item, overflow = 'constrain') {
1269
1259
}
1270
1260
1271
1261
export function ToTemporalYearMonth ( item , options = ObjectCreate ( null ) ) {
1272
- if ( Type ( item ) === 'Object' ) {
1262
+ if ( IsObject ( item ) ) {
1273
1263
if ( IsTemporalYearMonth ( item ) ) return item ;
1274
1264
const calendar = GetTemporalCalendarWithISODefault ( item ) ;
1275
1265
const fieldNames = CalendarFields ( calendar , [ 'month' , 'monthCode' , 'year' ] ) ;
@@ -1353,7 +1343,7 @@ export function InterpretISODateTimeOffset(
1353
1343
export function ToTemporalZonedDateTime ( item , options = ObjectCreate ( null ) ) {
1354
1344
let year , month , day , hour , minute , second , millisecond , microsecond , nanosecond , timeZone , offset , calendar ;
1355
1345
let offsetBehaviour = 'option' ;
1356
- if ( Type ( item ) === 'Object' ) {
1346
+ if ( IsObject ( item ) ) {
1357
1347
if ( IsTemporalZonedDateTime ( item ) ) return item ;
1358
1348
calendar = GetTemporalCalendarWithISODefault ( item ) ;
1359
1349
const fieldNames = CalendarFields ( calendar , [
@@ -1588,7 +1578,7 @@ export function CalendarFields(calendar, fieldNames) {
1588
1578
}
1589
1579
const result = [ ] ;
1590
1580
for ( const name of fieldNames ) {
1591
- if ( Type ( name ) !== 'String ' ) throw new TypeError ( 'bad return from calendar.fields()' ) ;
1581
+ if ( typeof name !== 'string ' ) throw new TypeError ( 'bad return from calendar.fields()' ) ;
1592
1582
ArrayPrototypePush . call ( result , name ) ;
1593
1583
}
1594
1584
return result ;
@@ -1600,7 +1590,7 @@ export function CalendarMergeFields(calendar, fields, additionalFields) {
1600
1590
return { ...fields , ...additionalFields } ;
1601
1591
}
1602
1592
const result = Reflect . apply ( calMergeFields , calendar , [ fields , additionalFields ] ) ;
1603
- if ( Type ( result ) !== 'Object' ) throw new TypeError ( 'bad return from calendar.mergeFields()' ) ;
1593
+ if ( ! IsObject ( result ) ) throw new TypeError ( 'bad return from calendar.mergeFields()' ) ;
1604
1594
return result ;
1605
1595
}
1606
1596
@@ -1703,11 +1693,11 @@ export function CalendarInLeapYear(calendar, dateLike) {
1703
1693
}
1704
1694
1705
1695
export function ToTemporalCalendar ( calendarLike ) {
1706
- if ( Type ( calendarLike ) === 'Object' ) {
1696
+ if ( IsObject ( calendarLike ) ) {
1707
1697
if ( HasSlot ( calendarLike , CALENDAR ) ) return GetSlot ( calendarLike , CALENDAR ) ;
1708
1698
if ( ! ( 'calendar' in calendarLike ) ) return calendarLike ;
1709
1699
calendarLike = calendarLike . calendar ;
1710
- if ( Type ( calendarLike ) === 'Object' && ! ( 'calendar' in calendarLike ) ) return calendarLike ;
1700
+ if ( IsObject ( calendarLike ) && ! ( 'calendar' in calendarLike ) ) return calendarLike ;
1711
1701
}
1712
1702
const identifier = ToString ( calendarLike ) ;
1713
1703
const TemporalCalendar = GetIntrinsic ( '%Temporal.Calendar%' ) ;
@@ -1768,11 +1758,11 @@ export function MonthDayFromFields(calendar, fields, options?: any) {
1768
1758
}
1769
1759
1770
1760
export function ToTemporalTimeZone ( temporalTimeZoneLike ) {
1771
- if ( Type ( temporalTimeZoneLike ) === 'Object' ) {
1761
+ if ( IsObject ( temporalTimeZoneLike ) ) {
1772
1762
if ( IsTemporalZonedDateTime ( temporalTimeZoneLike ) ) return GetSlot ( temporalTimeZoneLike , TIME_ZONE ) ;
1773
1763
if ( ! ( 'timeZone' in temporalTimeZoneLike ) ) return temporalTimeZoneLike ;
1774
1764
temporalTimeZoneLike = temporalTimeZoneLike . timeZone ;
1775
- if ( Type ( temporalTimeZoneLike ) === 'Object' && ! ( 'timeZone' in temporalTimeZoneLike ) ) {
1765
+ if ( IsObject ( temporalTimeZoneLike ) && ! ( 'timeZone' in temporalTimeZoneLike ) ) {
1776
1766
return temporalTimeZoneLike ;
1777
1767
}
1778
1768
}
@@ -4296,7 +4286,7 @@ export function ComparisonResult(value) {
4296
4286
}
4297
4287
export function GetOptionsObject ( options ) {
4298
4288
if ( options === undefined ) return ObjectCreate ( null ) ;
4299
- if ( Type ( options ) === 'Object' ) return options ;
4289
+ if ( IsObject ( options ) ) return options ;
4300
4290
throw new TypeError ( `Options parameter must be an object, not ${ options === null ? 'null' : `a ${ typeof options } ` } ` ) ;
4301
4291
}
4302
4292
0 commit comments