@@ -170,7 +170,8 @@ function abs(x: JSBI): JSBI {
170
170
return x ;
171
171
}
172
172
173
- const BUILTIN_CASTS = new Map < PrimitivePropertyNames , ( v : unknown ) => string | number > ( [
173
+ type BuiltinCastFunction = ( v : unknown ) => string | number ;
174
+ const BUILTIN_CASTS = new Map < PrimitivePropertyNames , BuiltinCastFunction > ( [
174
175
[ 'year' , ToIntegerThrowOnInfinity ] ,
175
176
[ 'month' , ToPositiveInteger ] ,
176
177
[ 'monthCode' , ToString ] ,
@@ -306,7 +307,7 @@ function ParseTemporalTimeZone(stringIdent: string) {
306
307
let { ianaName, offset, z } = ParseTemporalTimeZoneString ( stringIdent ) ;
307
308
if ( ianaName ) return ianaName ;
308
309
if ( z ) return 'UTC' ;
309
- return offset ;
310
+ return offset ; // if !ianaName && !z then offset must be present
310
311
}
311
312
312
313
function FormatCalendarAnnotation ( id : string , showCalendar : Temporal . ShowCalendarOption [ 'calendarName' ] ) {
@@ -1068,35 +1069,38 @@ export function LargerOfTwoTemporalUnits<T1 extends Temporal.DateTimeUnit, T2 ex
1068
1069
return unit1 ;
1069
1070
}
1070
1071
1071
- export function ToPartialRecord < B extends AnyTemporalLikeType > (
1072
- bag : B ,
1073
- fields : readonly ( keyof B ) [ ] ,
1074
- callerCast ?: ( value : unknown ) => unknown
1075
- ) {
1076
- if ( ! IsObject ( bag ) ) return false ;
1077
- let any : B ;
1072
+ export function ToPartialRecord < B extends AnyTemporalLikeType > ( bagParam : B , fieldsParam : ReadonlyArray < keyof B > ) {
1073
+ // External callers are limited to specific types, but this function's
1074
+ // implementation uses generic property types. The casts below (and at the
1075
+ // end) convert to/from generic records.
1076
+ const bag = bagParam as Record < PrimitivePropertyNames & keyof B , string | number | undefined > ;
1077
+ const fields = fieldsParam as ReadonlyArray < keyof B & PrimitivePropertyNames > ;
1078
+ let any = false ;
1079
+ let result = { } as typeof bag ;
1078
1080
for ( const property of fields ) {
1079
1081
const value = bag [ property ] ;
1080
1082
if ( value !== undefined ) {
1081
- any = any || ( { } as B ) ;
1082
- if ( callerCast === undefined && BUILTIN_CASTS . has ( property as PrimitivePropertyNames ) ) {
1083
- any [ property ] = BUILTIN_CASTS . get ( property as PrimitivePropertyNames ) ( value ) as unknown as B [ keyof B ] ;
1084
- } else if ( callerCast !== undefined ) {
1085
- any [ property ] = callerCast ( value ) as unknown as B [ keyof B ] ;
1083
+ any = true ;
1084
+ if ( BUILTIN_CASTS . has ( property ) ) {
1085
+ result [ property ] = ( BUILTIN_CASTS . get ( property ) as BuiltinCastFunction ) ( value ) ;
1086
1086
} else {
1087
- any [ property ] = value ;
1087
+ result [ property ] = value ;
1088
1088
}
1089
1089
}
1090
1090
}
1091
- return any ? any : false ;
1091
+ return any ? ( result as B ) : false ;
1092
1092
}
1093
1093
1094
1094
export function PrepareTemporalFields < B extends AnyTemporalLikeType > (
1095
- bag : B ,
1096
- fields : ReadonlyArray < FieldRecord < B > >
1097
- ) : Required < B > | undefined {
1098
- if ( ! IsObject ( bag ) ) return undefined ;
1099
- const result = { } as B ;
1095
+ bagParam : B ,
1096
+ fieldsParam : ReadonlyArray < FieldRecord < B > >
1097
+ ) : Required < B > {
1098
+ // External callers are limited to specific types, but this function's
1099
+ // implementation uses generic property types. The casts below (and at the
1100
+ // end) convert to/from generic records.
1101
+ const bag = bagParam as Record < PrimitivePropertyNames & keyof B , string | number | undefined > ;
1102
+ const fields = fieldsParam as ReadonlyArray < FieldRecord < typeof bag > > ;
1103
+ const result = { } as typeof bag ;
1100
1104
let any = false ;
1101
1105
for ( const fieldRecord of fields ) {
1102
1106
const [ property , defaultValue ] = fieldRecord ;
@@ -1105,15 +1109,11 @@ export function PrepareTemporalFields<B extends AnyTemporalLikeType>(
1105
1109
if ( fieldRecord . length === 1 ) {
1106
1110
throw new TypeError ( `required property '${ property } ' missing or undefined` ) ;
1107
1111
}
1108
- // TODO: two TS issues here:
1109
- // 1. `undefined` was stripped from the type of `defaultValue`. Will it
1110
- // come back when strictNullChecks is enabled?
1111
- // 2. Can types be improved to remove the need for the type assertion?
1112
- value = defaultValue as unknown as typeof bag [ typeof property ] ;
1112
+ value = defaultValue ;
1113
1113
} else {
1114
1114
any = true ;
1115
1115
if ( BUILTIN_CASTS . has ( property as PrimitivePropertyNames ) ) {
1116
- value = BUILTIN_CASTS . get ( property as PrimitivePropertyNames ) ( value ) as unknown as typeof bag [ keyof B ] ;
1116
+ value = ( BUILTIN_CASTS . get ( property ) as BuiltinCastFunction ) ( value ) ;
1117
1117
}
1118
1118
}
1119
1119
result [ property ] = value ;
@@ -1122,12 +1122,12 @@ export function PrepareTemporalFields<B extends AnyTemporalLikeType>(
1122
1122
throw new TypeError ( 'no supported properties found' ) ;
1123
1123
}
1124
1124
if (
1125
- ( ( result as Temporal . PlainDateLike ) [ 'era' ] === undefined ) !==
1126
- ( ( result as Temporal . PlainDateLike ) [ 'eraYear' ] === undefined )
1125
+ ( ( result as { era : unknown } ) [ 'era' ] === undefined ) !==
1126
+ ( ( result as { eraYear : unknown } ) [ 'eraYear' ] === undefined )
1127
1127
) {
1128
1128
throw new RangeError ( "properties 'era' and 'eraYear' must be provided together" ) ;
1129
1129
}
1130
- return result as Required < B > ;
1130
+ return result as unknown as Required < B > ;
1131
1131
}
1132
1132
1133
1133
// field access in the following operations is intentionally alphabetical
0 commit comments