Declare the runtime class or typeof of abstract types
Why
Untagged variants recognize payloads of abstract types only from a hard-coded list of stdlib type names, which knows no subclasses and is closed to bindings such as WebAPI's (#7147).
@instanceOf("Class") and @typeOf("…") on an abstract type or a type abbreviation state how its values are recognized at run time. The classifier reads them along the type's expansion chain: the outermost one decides, and the classes annotated further down a chain of private abbreviations are its superclasses. A class check excludes the subclasses that are cases too. Both imply that a value is never undefined. The name list stays as fallback for types without annotations. Editor completion offers both, and @notUndefined, which was listed with the file-level @@ decorators, now completes after a single @.
addedRepresentation untagged variant payload
@instanceOf("Animal") type animal@instanceOf("Dog") type dog = private animal@typeOf("symbol") type sym @unboxedtype t = Animal(animal) | Dog(dog) | Sym(sym)
representation
Animal(a)↦a, recognized by a instanceof Animal && !(a instanceof Dog)Dog(d)↦d, recognized by d instanceof DogSym(s)↦s, recognized by typeof s === "symbol"addedDiagnostic invalid annotation
@typeOf("undefined") type tdiagnostic
@typeOf expects one of "string", "number", "bigint", "boolean", "symbol", "function" or "object", not "undefined".Review
- Why
@instanceOf/@typeOfrather than one@runtime(...)attribute? They read like the JavaScript checks they produce, take a single string like@asand@tag, and sit next to the existing@notUndefined. - Why also on public abbreviations? The typed array types are public aliases of
TypedArray.t<'a>that users pass toTypedArrayfunctions, so they can only be told apart by the name as written, as the name list does.