-
-
Notifications
You must be signed in to change notification settings - Fork 9
TypeScript to Dart
This is a work in progress
The ts_ast
app just reads a .d.ts
file and, without too much filtering or business logic at all, dump the analyzed info into a JSON file.
The ts2dart
reads this JSON file and generates an object from a class for each TS declared type in the file, even if the type can not be directly transpiled to Dart.
This strategy consider that the Dart interop may evolve and let us better transpile TS features into Dart code in the future.
Now here is how we handle TS types:
The builder do some logic here to try to find a specific type that we can use, if not, we use dynamic
or Object
by default.
If all types are constants we ditch the union and use an enum instead:
export type Foo = 'one' | 'two';
Becomes an enum:
enum Foo {
one,
two
}
We filter the undefined
or null
to make a nullable type:
export type Foo = Bar | undefined | null;
Transpiles to:
typedef Foo = Bar?;
Everything else becomes dynamic
because we couldn't dissect an specific type definition, ie:
export type Foo = Bar | Daz;
The builder will generate a new type if the intersection is used in typedefs, if not, then dynamic is used.
export type Foo = Bar & Daz;
Transpiles to something like:
class Inline123 implements Bar, Daz {}
typedef Foo = Inline123;
Now when used in arguments:
declare function foo(bar: A & B);
Transpiles to something like:
void foo(dynamic bar);
You can overload a method in TS but not in Dart. The transpiller generates one method for each version so we can still be sound, ie:
interface Document {
createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K];
createElement(tagName: string, options?: ElementCreationOptions): HTMLElement;
}
From the above we generate a Record
called createElement
with two function properties: $1
and $2
.
For the first version ($1
) we identify that the return type is bound to an enum
, thus we can then generate a signature that the return type can be infered:
// div is infered to the type HTMLDivElement
final div = js.document.createElement.$1(js.HTMLElementTagNameMap.div);
The second version in Dart has no difference from the TS one.
There are types that can be directly transpiled to Dart:
- Classes/interfaces
- Typedefs
- Enums
- Tuples
- Functions