Language features
Every TypeScript feature: whether Lucent supports it, and what to write instead when it doesn't.
Declarations and modules
Section titled “Declarations and modules”| Feature | Supported | Note |
|---|---|---|
export function, export class, export const, export let | yes | What JavaScript can use. Constants cross once, when the module loads. |
export type, export interface, export enum | yes | Enums reach JavaScript as frozen objects. Their values aren't checked at the boundary. |
Imports between modules, import type | yes | Relative imports of other *.lucent.ts files, and lucent:* modules. |
| Imports of npm packages | no | Only other modules and lucent:* (LUCENT3001). |
export default, export { … }, export * from | no | Export each declaration where it's declared (LUCENT3003). |
Components: an exported function of a .lucent.tsx module that returns a platform view | no | Not rendered yet. Lucent checks them (LUCENT3020 to LUCENT3023) and leaves them out of the module's JavaScript. |
| Top-level statements | no | Only declarations at the top level (LUCENT3002). |
var | no | Use let or const (LUCENT1001). |
| Feature | Supported | Note |
|---|---|---|
number, string, boolean, null, undefined | yes | A number is a double with JavaScript's arithmetic. |
bigint | yes | Any precision; values that fit in 64 bits don't allocate. Loose == with a number or string is rejected (LUCENT1002). |
| Object types, interfaces without methods | yes | Become C++ structs, one per shape. |
Arrays, tuples, Record<string, T>, Map, Set, Uint8Array, Date, RegExp | yes | Reference types, shared inside Lucent as in JavaScript. |
| Unions and discriminated unions | yes | Narrowed by typeof, instanceof, a discriminant field, or a null check. |
Optional fields and parameters, T | null, T | undefined | yes | |
| Generics | yes | Functions, classes and interfaces. Not exported to JavaScript (LUCENT2007). |
| String literal types | yes | Checked by TypeScript; at the boundary, any string is accepted. |
any, and unknown outside catch | no | Use a concrete type, a union or a generic (LUCENT2001). |
Intersections, object, symbol | no | No native representation (LUCENT2002). |
| Object types with methods or getters | no | Use a class (LUCENT2002). |
WeakMap, WeakRef, typed arrays other than Uint8Array | no | LUCENT2002. |
Statements and expressions
Section titled “Statements and expressions”| Feature | Supported | Note |
|---|---|---|
if, switch, for, for…of, for…in, while, do…while, labels | yes | |
try, catch, finally, throw | yes | Only Error values can be thrown (LUCENT1006). |
using declarations | yes | Disposed by a class's [Symbol.dispose]() on every way out of the block. Not await using, or using directly in a case clause (LUCENT1001). |
Every operator, ??, ?., !, **, logical assignment | yes | ! throws a TypeError when the value is missing. === compares arrays, maps, sets, records and class instances by reference, tuples by their elements; functions cannot be compared (LUCENT1002). |
| Template literals, spread, destructuring | yes | Not object rest or computed keys in destructuring (LUCENT1004). |
obj[key] with a computed key on an object type | no | Use a Record or a Map (LUCENT1001). |
delete | yes | On a Record. Use Map.delete for maps. |
in | yes | On a Record only (LUCENT1002). |
eval, new Function | no | LUCENT1003. |
for await | no | LUCENT1009. |
Functions and classes
Section titled “Functions and classes”| Feature | Supported | Note |
|---|---|---|
| Function declarations, arrows, closures, recursion | yes | Closures share the variables they capture. |
| Default and rest parameters | yes | Not rest parameters in function types (LUCENT2002). |
Generators, yield, yield* | yes | Not the value of yield, a generator's return value, or async generators. |
Classes: fields, constructors, methods, getters, setters, static, private, #private | yes | |
extends a Lucent class, extends Error, abstract | yes | |
implements an interface | yes | Needed to use a class as the interface (LUCENT2008). |
| Nested classes, static blocks, index signatures on classes | no | LUCENT1001, LUCENT1005. |
call, apply, bind, this outside a class | no | LUCENT1003, LUCENT1001. |
| Object literals with methods, getters or setters | no | Use a class (LUCENT1001, LUCENT2002). |
| Feature | Supported | Note |
|---|---|---|
async functions and methods, await | yes | Exported ones run on the Lucent thread. |
Promise.all, Promise.resolve, Promise.reject, new Promise | yes | |
Promise.race, Promise.allSettled, Promise.any, .then | no | LUCENT1003. |
AbortSignal, AbortController | yes | aborted, throwIfAborted(), addEventListener("abort", …). Not signal.reason. |
Differences from JavaScript
Section titled “Differences from JavaScript”| JavaScript | Lucent |
|---|---|
arr[i] = v past the end makes holes | throws a RangeError; append with push |
| values passed to native code are shared | copied at the boundary; shared inside Lucent |
| garbage collection frees cycles | reference counting never frees a cycle |
deep recursion throws a RangeError | may overflow the native stack |
== converts between numbers, strings and booleans (1 == "1") | such comparisons are refused (LUCENT1002); compare with === after converting |
| functions compare by reference | comparing two functions is refused (LUCENT1002): a function value has no stable identity |
| tuples are arrays and compare by reference | tuples are values: === compares their elements |
two subarray() views of one range are different objects | they are one view: === compares a view's buffer and range |
console.log(obj) pretty-prints | prints String(obj) |
str.split(regexp) gives undefined for a group that didn't match | gives "" |
JSON.parse returns whatever the text holds | the text must match the type; a mismatch throws a TypeError naming the path |
JSON.stringify keeps the parsed text's key order | keys follow the declared type's order |
| an abort reason can be any value | reasons from JavaScript become errors; abort() in Lucent takes an Error |
a subclass field read from the base constructor is undefined | it reads the type's default: 0, "", false |
| any object with the right members fits an interface | only classes that declare implements |