Conversions
This section describes which type conversions are available.
Casts may occur as either t(v) (strict conversion) or v as t (optional conversion). The behavior of the call operator over a type may not always be a conversion depending on if t implements the self-attached meta::invoke() meta-method.
v as t // returns t?. failure returns null
v as! t // failure throws a TypeError (as-strict)
t(v) // same as "v as! t"
Constant coercions
Constant coercions occur implicitly both at compile-time and runtime, converting a constant into another constant.
| Kind | Result |
|---|---|
undefined to flag enumeration | Interned instance whose value is zero (0). |
null to flag enumeration | Interned instance whose value is zero (0). |
undefined to t containing both undefined and null | undefined |
undefined to t containing undefined and no null | undefined |
undefined to t containing null and no undefined | null |
null to t containing undefined but not null | undefined |
null to t containing null but not undefined | null |
null to t containing both undefined or null | null |
Numeric constant to * or Object | Equivalent constant of the target type. |
String constant to * or Object or union containing string | Equivalent constant of the target type. |
Boolean constant to * or Object or union containing boolean | Equivalent constant of the target type. |
Namespace constant to * or Object or union containing Namespace | Equivalent constant of the target type. |
Type constant to * or Object or union containing Class | Equivalent constant of the target type. |
| Numeric constant to another compatible numeric type | Numeric constant with value coerced to target type. |
| Numeric constant to union containing at least one compatible numeric type | Numeric constant of the target type containing value coerced to the containing numeric type, preferring the same numeric type or otherwise the first numeric type found. |
NaN to float | NaN |
NaN to decimal | NaN |
-Infinity to float | -Infinity |
+Infinity to float | +Infinity |
-Infinity to decimal | -Infinity |
+Infinity to decimal | +Infinity |
Implicit coercion
Implicit coercions occur implicitly both at compile-time and runtime, after trying a constant coercion.
| Kind | Result |
|---|---|
From * | |
To * | |
| From numeric type to compatible numeric type | |
| To covariant (includes base classes, same parameterized type (if current type arguments implicitly coerce to the target type arguments), implemented interfaces, unions and inherited record type) | |
| From union to compatible union | |
| From union member to union | |
| From union to a common base type | For example, given type U = (B, C), a var a:A = u; declaration is valid as long as B and C share A as a base type. |
| From structural function type to another compatible function type | |
From t type parameter to t? |
Note:
interfacetypes inheritObject.
Parameterized types
ShockScript allows implicit coercions from t.<...> to t.<...> where t is a parameterized type, where the final type contains type arguments which the original type’s type arguments implicitly coerce to.
Note: Implicitly coercing an Array, Map or Set type to use covariant element types is allowed; however overwriting the collection later with unexpected element values may throw a TypeError during runtime.
For other types, using an unexpected type somewhere in place of type parameters may lead to an internal error during runtime.
Casts
Casts occur when resolving v as t or t(v), after trying an implicit coercion.
| Kind | Result |
|---|---|
To contravariant (from interface to interface subtype, from class to subclass, or record type subtype) | |
| To union member | |
From * or Object to interface | |
To a contravariant [t] type | A new Array filtering out incompatible elements. |
To a possibly incompatible Map.<K, V> type | A new Map filtering out incompatible fields. |
To a contravariant Set.<t> type | A new Set filtering out incompatible elements. |
| To same parameterized type if not Array, nor Map and nor Set and if current type arguments can cast to the target type arguments | E.g. c.<*> to c.<double> |
string to enumeration | Identification of an enumeration variant by its string name. |
| Number to enumeration (using the same numeric type) | For regular enumerations, identifies a variant by its numeric value. For flag enumerations, identifies variant bits. |
To string | For undefined, returns "undefined"; for null, returns "null"; for other types, invokes toString(). |
To boolean | Evaluates truthy value. |
To double | Forced conversion to double-precision floating point. |
To float | Forced conversion to single-precision floating point. |
To decimal | Forced conversion to 128-bit decimal number. |
To byte | Forced conversion to 8-bit unsigned integer. |
To short | Forced conversion to 16-bit signed integer. |
To int | Forced conversion to 32-bit signed integer. |
To uint | Forced conversion to 32-bit unsigned uninteger. |
To long | Forced conversion to 64-bit signed integer. |
To bigint | Forced conversion to an arbitrary range integer. |
| Record type into equivalent record type of non-uniform field order | |
| From type parameter |
Note:
interfacetypes inheritObject.
Parameterized types
ShockScript allows casts from t.<...> to t.<...> where t is a parameterized type, where the final type contains type arguments which the original type’s type arguments may cast to.
Note: These conversions are always safe for Array, Map and Set types, as they create new objects.
For other types, the resulting object is the same, therefore unexpected type or property related errors can occur during runtimes.