-
-
Notifications
You must be signed in to change notification settings - Fork 65
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
Building TypeScript type definitions, along with some JSDoc #210
base: master
Are you sure you want to change the base?
Conversation
Possibly due to [TypeScript#51819], the exported declarations are quite incomplete when re-exporting using `module.exports.key = value` syntax. [TypeScript#51819]: microsoft/TypeScript#51819
Attempts to make tsc happy. Possible bugs: - lapi.js: there is no ts.value but ts.realstring - liolib.js: "19.x.x" > 6 is always false - loadlib.js: not lua_pushstring but lua_pushfstring - loslib.js: Uint8Arrays instead of strings passed to nodejs functions - lstrlib.js: wrong args to luaL_argcheck - ltm.js: extraneous new
New dependency changes detected. Learn more about Socket for GitHub ↗︎ 👍 No new dependency issues detected in pull request Bot CommandsTo ignore an alert, reply with a comment starting with Pull request alert summary
📊 Modified Dependency Overview:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Please forgive any stupid review comments, as typescript isn't something I've really used before.
I only got half way through reviewing and my attention faded; so this is only a partial review.
Other misc note: I think I somewhat intended that fengari strings being Uint8Array
was meant to be opaque to the user. Is it possible to make the string type distinct Uint8Array
-like? or possibly an alias?
src/defs.js
Outdated
let luastring_indexOf; | ||
if (typeof (new Uint8Array().indexOf) === "function") { | ||
luastring_indexOf = function(s, v, i) { | ||
return s.indexOf(v, i); | ||
}; | ||
} else { | ||
/* Browsers that don't support Uint8Array.indexOf seem to allow using Array.indexOf on Uint8Array objects e.g. IE11 */ | ||
let array_indexOf = [].indexOf; | ||
let array_indexOf = [0].indexOf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I'm sorta surprised this works
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually because TypeScript treats []
as Array<undefined>
and forbids using it as Array<number>
. Probably using Array.prototype.indexOf
is more understandable.
src/defs.js
Outdated
@@ -232,6 +288,7 @@ const from_userstring = function(str) { | |||
throw new TypeError("expects an array of bytes or javascript string"); | |||
} | |||
} | |||
// @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? / is there some other decorator we could use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, TypeScript is called AnyScript for a reason - it fails to deduce that str
has to be Uint8Array
. An alternative is to make things more explicit:
const from_userstring = function(str) {
- if (!is_luastring(str)) {
+ if (!(str instanceof Uint8Array)) {
(One may also use // @ts-expect-error
, but neither offers a way to specify the suppressed error type.)
src/defs.js
Outdated
LUA_TSHRSTR: 0, | ||
LUA_TLNGSTR: 0, | ||
LUA_TNUMFLT: 0, | ||
LUA_TNUMINT: 0, | ||
LUA_TLCL: 0, | ||
LUA_TLCF: 0, | ||
LUA_TCCL: 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes the code harder to understand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript does not track type info of the fields assigned only after object initialization. What about:
const LUA_OK = 0;
const LUA_YIELD = 1;
const LUA_ERRRUN = 2;
const LUA_ERRSYNTAX = 3;
const LUA_ERRMEM = 4;
const LUA_ERRGCMM = 5;
const LUA_ERRERR = 6;
const LUA_TSHRSTR = LUA_TSTRING | (0 << 4); /* short strings */
const LUA_TLNGSTR = LUA_TSTRING | (1 << 4); /* long strings */
const LUA_TNUMFLT = LUA_TNUMBER | (0 << 4); /* float numbers */
const LUA_TNUMINT = LUA_TNUMBER | (1 << 4); /* integer numbers */
const LUA_TLCL = LUA_TFUNCTION | (0 << 4); /* Lua closure */
const LUA_TLCF = LUA_TFUNCTION | (1 << 4); /* light C function */
const LUA_TCCL = LUA_TFUNCTION | (2 << 4); /* C closure */
const thread_status = {
LUA_OK,
LUA_YIELD,
LUA_ERRRUN,
LUA_ERRSYNTAX,
LUA_ERRMEM,
LUA_ERRGCMM,
LUA_ERRERR,
LUA_TSHRSTR,
LUA_TLNGSTR,
LUA_TNUMFLT,
LUA_TNUMINT,
LUA_TLCL,
LUA_TLCF,
LUA_TCCL,
};
src/fengari.js
Outdated
module.exports.lua = lua; | ||
module.exports.lauxlib = lauxlib; | ||
module.exports.lualib = lualib; | ||
module.exports = exported; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recall that this caused problems in some ancient node version; or was it an issue with particular minifiers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to cause problems when there is a cyclic dependency: https://stackoverflow.com/questions/63371870/object-assignmodule-exports-vs-module-exports
Unfortunately, loadlib.js
depending on fengari.js
creates exactly a dependency cycle. Maybe we can defer requiring fengari.js
(which is only used inside a library loading function)?
(I just tried Object.assign
and it turns out TypeScript empties all types definitions, leaving only export {};
.)
@@ -85,7 +85,8 @@ const setallfields = function(L, time, utc) { | |||
setfield(L, "month", (utc ? time.getUTCMonth() : time.getMonth()) + 1); | |||
setfield(L, "year", utc ? time.getUTCFullYear() : time.getFullYear()); | |||
setfield(L, "wday", (utc ? time.getUTCDay() : time.getDay()) + 1); | |||
setfield(L, "yday", Math.floor((time - (new Date(time.getFullYear(), 0, 0 /* shortcut to correct day by one */))) / 86400000)); | |||
setfield(L, "yday", Math.floor( | |||
(time.valueOf() - (new Date(time.getFullYear(), 0, 0 /* shortcut to correct day by one */)).valueOf()) / 86400000)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised typescript can't figure out this line without the .valueOf()
. It really makes it less readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly true. I really cannot think of a better way to do this though. (Or maybe just @ts-ignore
.)
Using |
- Define new variables when reusing older ones confuse tsc - Pass buffers to nodejs functions to avoid decoding errors - Refine type info and rid @ts-ignore
@gudzpoz @daurnimator |
@gudzpoz @daurnimator I would like to contribute to this PR if there is anything pending it. |
@rzvxa Please do 👍 |
@giann Thanks for your replay, |
@giann @daurnimator I have errors in tests, even in the master branch of Fengari. Is something wrong with my setup? If not, please let me know if you know about this failing test. |
IIRC, I was waiting for a full review before deciding on what to do next. To summarize things a bit, there are a few things that we need to finalize in this PR:
Also, @rzvxa if you are getting errors, would you please at least attach some of the test output (or, even better, reproducing steps)? |
@gudzpoz Failed test also fails in the master branch of main project, So it has noting to do with you changes and bug fixes.
|
@gudzpoz I think it's better for you to move all of the bug fixes to their own PRs but I think we can keep both JSDocs and typescript definition together in this PR. Some of the TS warnings can be totally ignored, They are there to stop the developer from shooting themselves in the leg, But for example over here we can leverage typescript instead of actually parsing the number from boolean or use ternary operations. |
https://jsfiddle.net/xdueqj92/1/ |
https://docs.joshuatz.com/cheatsheets/js/jsdoc/#casting-and-type-coercion-in-jsdoc |
@gudzpoz I would love to help with documentation and typing. I want this project to have types and get some maintenance so I can easily use it in my open-source project with no worries. The only fair thing for me to do is to contribute to this project, for myself and anyone who wants to have access to Lua in the JS environment. It's a niche community but I'm sure some projects would love to have a stable lua implementation in Javascript. If you don't mind, I can collaborate with you on this PR and every other bug fix that comes up in this process. For documentation, we can base our documentation on the Lua project itself. After this PR we can consider working together on the garbage collection implementation which is currently missing. Thanks! |
I've cherry picked a few of the fixed into master |
Thank you very much for your work! |
@leopoldhub No, currently I am not working on this PR and might have lost track of the state of it over the last year... Now that the fixes have been merged, it seems to me that it only needs a bit more fixes to be ready for a second review:
Unfortunately, I haven't touched JS/TS for a while and might need quite some time to pick up this PR again. I've added you as a collaborator to the merging fork, if you are interested, you are welcome to continue the work on this PR! |
This PR attempts to address #135 by generating
.d.ts
files from.js
directly. Some JSDoc is added to provide better type hints.Most of the changes are just JSDoc comments, but running
tsc --checkJs
does reveal some bugs (or maybe not, I don't know):lua_assert
is supplied two params in several places, while it declares only one,There are some other code changes just to make
tsc
happy, and they should not incur any behavioral changes.This PR can be partially tested with
tsc --checkJs
, which will also run onnpm run test
.P.S. I am not that sure about the correctness of the JSDoc though, which was initially generated with a script scraping the C API.