New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeScript bindings #232
Comments
|
Exactly.
Yes. I need it in some cases when integrating existing JS code with Fable-generated code (e.g. to create a In an ES2015 project this is very straightforward. A simple But for a TypeScript project this also requires a For now I did some dummy declarations only for the types I need, e.g.: // es2015.d.ts
export var Array: any;
export var List: any; just to keep the compiler happy. I will be playing a bit more with it. Let's see what happens :) |
I thought the TypeScript was able to read an ES2015 module even without the type definitions, it seems I was wrong 😉 I wrote a very simple script to read the (static) members of Another solution is, like |
Me too! Until you use it and start to see dozens of "
It will solve only part of the problem. Any automated solution based on a .js file could at most generate a "skeleton" file. It will yet require some human intervention to add the types. E.g., in the line
We have no (automated) means to know about the expected type of
Hm... Yes! This would indeed be better. Using a .ts file carries "more expressiveness" than the current .js (ES2015) one. It would also improve fable-core documentation in some way. HOWEVER... it will make the build system more complex (it will require TypeScript to build Fable) and also the maintenance of fable-core. Any modification in fable-core would require a TypeScript connoisseur to make the change. Sincerely: unless you are very comfortable with TypeScript I would recommend against this and just keep a separate .d.ts file for now. It is a fantastic language, but it can give you wrinkles sometimes... 😄 |
Not a very good practice but the current I haven't worked that much with TypeScript but I'm comfortable with the language and given the fact that advanced F# users (that is, potential Fable contributors) usually know well Microsoft technologies, probably they can handle TypeScript. Also, maintaining a different In conclusion, I'd be in favour of writing |
Already working on it ;) |
Please see #236. I did a small declaration (for List functions only) just to assess the work needed. The declarations are far from the ideal. They can be much more strict (using generics, less "any" types, etc). I made them quickly, just to make it work. I will work now in the changes needed to compile es2015.js using TypeScript instead of Babel. Then we can compare both options (keeping a .d.ts separately vs build it entirely from TypeScript). |
I panic whenever two files must be kept in sync without anything that forces that in the build process 😉 so I'd still be in favour of writing About generating |
I surely understand ;) I'm working on a "mini-fable-core.ts" right now. I believe I can push a first version soon. Then we can discuss the possible options (classes, interfaces, namespaces, etc.) |
Initial proof-of-concept to port It is far from complete. To build: From project root folder, run:
This will create
Please, compare the generated BTW: I spent the last hour trying to compile the generated Also: please note that the TSC compiler target must be ES2015. Any other target and the compiler will not recognize iterators and generators. This will hopefully change in TypeScript 2.0. But, for now, we will probably need Babel if the output of TSC isn't enough. If no problems arise, I can proceed to the conversion of the remaining |
When compiling with Babel you need to pass the plugins you want to use, and they can be a lot to convert from ES2015 to ES5 for example (that's why they usually use presets). In the Oh my, TypeScript cannot compile generators to ES5? Come'n Microsoft! Anyways, as said above, iterators are created with no ES2015 syntax in It'd be nice if you try to keep as many lines as common between |
Yeah! I'm aware of Babel plugins and presets. But I couldn't find a combination to output the
Agreed! I started this way. However, after several revisions of the code I did choose to make some minor "syntatic" changes (like changing function delegates to lambdas, to use My idea is to write the source in the most TypeScript-way, to enjoy the benefits of the language, but which -- after the transpile -- can get to something very similar to the current |
Found it! The problem wasn't the combination of Babel plugins but its options. The TypeScript code: export class Seq<T> {
static fold<T, ST>(f: (previousValue: ST, currentValue: T, currentIndex?: number) => ST, acc: ST, xs: Iterable<T>): ST {
if (Array.isArray(xs) || ArrayBuffer.isView(xs)) {
return (xs as Array<T>).reduce(f, acc);
} else {
let cur: IteratorResult<T> = null;
for (let i = 0, iter = xs[Symbol.iterator](); ; i++) {
cur = iter.next();
if (cur.done) {
break;
}
acc = f(acc, cur.value, i);
}
return acc;
}
}
static foldBack<T, ST>(f: (currentValue: T, previousValue: ST, currentIndex?: number) => ST, xs: Iterable<T>, acc: ST): ST {
const arr = Array.isArray(xs) || ArrayBuffer.isView(xs) ? xs as Array<T> : Array.from(xs);
for (let i = arr.length - 1; i >= 0; i--) {
acc = f(arr[i], acc, i);
}
return acc;
}
} TSC |> Babel --preset ES2015 with var Seq = exports.Seq = function () {
function Seq() {
_classCallCheck(this, Seq);
}
Seq.fold = function fold(f, acc, xs) {
if (Array.isArray(xs) || ArrayBuffer.isView(xs)) {
return xs.reduce(f, acc);
} else {
var cur = null;
for (var i = 0, iter = xs[Symbol.iterator]();; i++) {
cur = iter.next();
if (cur.done) {
break;
}
acc = f(acc, cur.value, i);
}
return acc;
}
};
Seq.foldBack = function foldBack(f, xs, acc) {
var arr = Array.isArray(xs) || ArrayBuffer.isView(xs) ? xs : Array.from(xs);
for (var i = arr.length - 1; i >= 0; i--) {
acc = f(arr[i], acc, i);
}
return acc;
};
return Seq;
}(); Current fable-core.js: var Seq = exports.Seq = {};
// ...
Seq.fold = function (f, acc, xs) {
if (Array.isArray(xs) || ArrayBuffer.isView(xs)) {
return xs.reduce(f, acc);
} else {
for (var i = 0, cur = null, iter = xs[Symbol.iterator]();; i++) {
cur = iter.next();
if (cur.done) {
break;
}
acc = f(acc, cur.value, i);
}
return acc;
}
};
Seq.foldBack = function (f, xs, acc) {
var ar = Array.isArray(xs) || ArrayBuffer.isView(xs) ? xs : Array.from(xs);
for (var i = ar.length - 1; i >= 0; i--) {
acc = f(ar[i], acc, i);
}
return acc;
};
// ... Now THAT'S what I'm talking about. 😉 As you can see, even making heavy use of TypeScript features (classes, generic types, etc) we can yet produce the same output which ES2015.js |> Babel does today to generate I will push some more changes soon, including this process in the build script. Then we can better assess the results. |
Nice! Now I remember there was something about that in Babel Discuss 😅 |
Updated #240
Important: you'll need to run I will add some more classes into |
BTW: I fixed a minor glitch when running |
Tomas also found this problem and sent a PR ;) I'm on Windows now too and I'm trying to fix things again to be easily open Fable on VS but I've found a problem that I'm trying to fix. About passing Babel plugins via CLI, it's possible but they're always resolved locally. My dirty fix for that was to pass the plugins installed in |
Hahahah. No. Forget about it. @tpetricek won the race with #241 😂 |
Sure! However, the problem isn't the PLUGIN but its OPTIONS 😉. Please see: {
"presets": [
"es2015"
],
"plugins": [
"transform-es2015-modules-umd",
[
"transform-es2015-classes",
{
"loose": true
}
]
]
}
I tried to keep everything like you did, but I couldn't find a way to pass that |
Two PR for the same problem in the same day and now two comments about it at almost the same time. Must be some record. 😅 |
Latest changes merged in #240 Everything like before. Same instructions apply. Just replace |
Added some more types in #240. This time choosing to keep the generated |
Thanks! I'll have a look later... I think I need to take a rest from Fable this weekend ;) Sorry for so many changes in the build process, I'm trying to find the best structure so it's easier for other people to contribute. Hopefully it should be fine now 👍 |
New push in #240. Full implementation of (the original code, built from Problem: The tests are failing with an weird error (" Have a great weekend! |
Latest update in #240 -- All tests passing now! 🎉 About the I also did some minor improvements in some tests to catch a few quirks I was getting. From this one I believe it would be possible to start using TypeScript sources to generate the official If you choose to merge this, please consider the following:
|
Fantastic work! I'll check it more carefully but it's looking good so far 👍 Though, to be honest, I feel a bit uneasy if you had to tweak the tests to make them pass, as this can reveal fails in the compilation process. What were exactly the quirks you were getting? Also, about |
Don't worry 😉. I just expanded them in some cases (like in These changes were made only to help me to find problems in my port. Not to compromise the tests 😅. You can test them against
Perfect! 👍 |
On a second thought, we should not remove the Doing this would be in detriment of anyone who wants to integrate existing ES2015 code with Fable (like, for example, myself 😄). I propose we keep the files as follow:
|
Hmmm, still I'd prefer if you add to the tests but don't replace anything. This is because so far I had many surprises of apparently trivial changes in the tests that revealed subtle problems with the compilation. I'll add some comments to you PR but in general I sleep better if I don't see red in the tests, only green... both for the results and the git diffs 😉 |
Hahaha... Got it! 😄 You are absolutely right. I did remove the code under the assumption my new code would cover the old one. I'm fixing this right now. |
Thanks! About the file structure, I agree with that 👍 Only thing is: at what point are ES2015 features (besides modules) transformed? When converting from |
This one. TypeScript are being told to target ES2015. In this target, as a rule of thumb, you can think of it more as a "types enforcer" than a "coding generator". The "heavier" transformations (from ES2015 to ES5) are made by Babel plugins. |
Closing the issue as the PR is already merged. Please feel free to send additional PRs to improve the definitions. Thanks a lot for your contribution! |
To integrate Fable-generated code with an ES2015 project is a breeze. Plain simple. It just works.
However, the same cannot be said for TypeScript projects.
fable-core
requires a.d.ts
file. Has anyone already made one? (I can work on it)The same for every
.js
file created by Fable. Could the compiler generate it automatically for us? How hard it will be?The text was updated successfully, but these errors were encountered: