An explicit cast between numeric types and between a class and its base/derived type lowers to the expression itself — the cast is erased.
float f = (float)intValue;
Hero h = (Hero)unit;local f = intValue
local h = unitis checks emit a type metadata lookup using a SF__.TypeIs__ helper:
function SF__.TypeIs__(obj, target)
if obj == nil then return false end
local type = obj.__sf_type
while type ~= nil do
if type == target then return true end
if type.__sf_interfaces ~= nil and type.__sf_interfaces[target] then return true end
type = type.__sf_base
end
return false
end
function SF__.TypeAs__(obj, target)
if SF__.TypeIs__(obj, target) then return obj end
return nil
endif (unit is Hero)
{
DoHeroThings();
}if SF__.TypeIs__(unit, SF__.Hero) then
DoHeroThings()
endis null and is not null lower to direct nil checks. The nullable suppression operator is erased before lowering, so value! is not null has the same runtime shape as value is not null.
return value! is not null;return (not (value == nil))Inside generic methods, is T name in an if condition lowers to a TypeIs__ check against the hidden runtime type-argument parameter and binds name to the tested value for the if body.
if (component is T typed)
{
return typed;
}do
local typed = component
if SF__.TypeIs__(typed, T) then
return typed
end
endas lowers to a conditional return of the value or nil.
Hero? h = unit as Hero;local h = SF__.TypeAs__(unit, SF__.Hero)Every emitted type table receives Name and FullName metadata fields:
SF__.MyName.Queue = SF__.MyName.Queue or {}
SF__.MyName.Queue.Name = "Queue"
SF__.MyName.Queue.FullName = "MyName.Queue"Static fields named Name or FullName are emitted later and can intentionally overwrite these defaults.
GetType() on a class instance lowers to the runtime type metadata stored on the object:
var q = new Queue();
var t = q.GetType();local q = SF__.MyName.Queue.New()
local t = q.__sf_typeType.Name and Type.FullName lower to runtime metadata field reads:
BJDebugMsg(t.Name);
BJDebugMsg(t.FullName);
BJDebugMsg(q.GetType().FullName);BJDebugMsg(t.Name)
BJDebugMsg(t.FullName)
BJDebugMsg(q.__sf_type.FullName)checked casts, unchecked casts, declaration patterns with binding outside an if condition (e.g., return unit is Hero h), switch pattern matching, GetType() on structs, and System.Type properties other than Name and FullName produce a transpiler error.