It says in the site that Gleam can do this.
I seen this https://gleam.run/news/gleam-v0.22-released/
[javascript]
typescript_declarations = true
Doesn't seem to do anything, I cannot see any d.ts files created anywhere.
thanks
1 messages · Page 1 of 1 (latest)
It says in the site that Gleam can do this.
I seen this https://gleam.run/news/gleam-v0.22-released/
[javascript]
typescript_declarations = true
Doesn't seem to do anything, I cannot see any d.ts files created anywhere.
thanks
are you building js? unless you've also set target=javascript in your toml file you'll need to run gleam build --target javascript
have you tried doing a clean build? i didn't need to when i enabled it but i know others have needed it. gleam clean && gleam build
trying
No diff
Do I need to annotate the types in Gleam that I want to export somehow?
I think there's an option in the gleam.toml file for generating TS definitions
are you checking for .d.ts specifically? gleam generates .d.mts to match the .mjs files it generates
I can't see anything resembling types being generated
Try putting
[javascript]
typescript_declarations = true
in your gleam.toml
And then delete your build dir
I have that, will try deleting the build dir
Gleam caches builds if there’s nothing to build you wont see any additional artefacts ^.^
In which dir are those definitions supposed to appear?
Does the mjs file need to import the gleam file or something?
wait, are you talking about gleam? or about lustre? gleam doesn't generate anything in priv/static
I found a definition file deep in the build folder.
Ok I guess this makes sense for publishing a library.
Hmm, so what I would like to achieve is to have typechecking on my mjs files via typescript (jsdocs I suppose?).
E.g. if I have a type in gleam User
I want to type check that a function in JS returns a User as expected by gleam.
Looking, thanks
i'm not sure i understand the problem. generate types out of your gleam library, publish your gleam library with that type information, and then use typescript in the project that's using the library and it should just work?
TypeScript is especially guilty of this because it makes it extremely non obvious because it tries to allow for incremental addoption, but gleam's FFI can suffer from this too - there is no explicit type checking at the boundaries of your type safe code. if you write untyped javascript then you're on your own to make sure you do the right thing, both when calling into type safe code or calling out from type safe code via FFI. If you care about ensuring the types are correct at the boundaries then you need runtime checks.
It is an app, with some parts in Gleam and some in JS
So, not a Gleam lib that will be used somewhere else
i'm not sure i understand the problem. generate types out of your gleam library, publish your gleam library with that type information, and then use typescript in the project that's using the library and it should just work?
conceptually what you describe is simple, but please remember that it is not actually documented where any of this build stuff goes, nor is there any guidance on how to "publish your gleam library with that type information" in a way that is meaningful to js/ts users
true
i was definitely assuming some knowledge about the javascript side of things, and for reference gleam dumps the built files into build/javascript/[package] which includes the type information. This whole process is something I want to document better myself as I start working towards publishing the commonmark package into NPM as well. a discord thread is probably not the right place to start writing up extensive documentation though, especially since you'll probably want a bundler and dts rollup as part of that process and each of those could be an article in their own right.
i think they just want to type their ffi code with gleam types, nothing crazy 🙂
I will like to have typed functions in the JS side eg.
export async function generateFoo(): Promise<Foo> {
return ...
}
Where Foo is a type defined in Gleam
I was trying ts-gleam, followed the instructions, but don't know what is supposed to do when running gleam build.
How is that going to interact with typescript?
Well, thanks for the help, will come back to this later
what do you mean "interact with typescript"?
gleam doesnt interact with any of your ffi files save for moving them from src/ to build/dev/javascript. if you'd like ts to check your code you will need to run ts, similarly if you'd like ts to build your code you'd have to run tsc.
kinda like how if you wrote ports with typescript elm wouldnt know anything about it, you'd still have to handle the ts files somehow and elm make wouldnt do that for you
I would like to generate the .d.ts files in my source folder, so I can import those types in typescript files. And then run tsc.
Kind like what https://elm-ts-interop.com/ does
Run a command that generates the type definitions in some place where can be imported by TS
the types are generated in "some place" 😅 as explained above they're generate in build/dev/javascript
you can import those in your ts code
So is the idea to commit the build directory in a repo?
Anyway, this is very helpful, thanks
no i wouldnt think so, anyone using your project will also have the gleam compiler around necessarily
I'm just realising that the generated types cannot be used as is either.
Gleam generates JS classes for custom types.
e.g.
pub type Thing {
Thing(
name: String
)
}
Is generated as
export class Thing extends _.CustomType {
constructor(name: string);
name: string;
}
Which is probable useful when you have variants.
But all I want is to return a record from TS. e.g.
type Thing = {
name: string
}
I'm confused as to why that's an issue
If I have a function in JS like
import { Thing } from "../build/dev/javascript/app/app.mts";
export function generateThing(): Thing {
return {
name: "thing1"
}
}
The types won't match
ts records aren't compatible with gleam types
you wouldnt be able to pattern match on them
Unsure what would happen if I return a class instance from JS, trying.
So return new Thing("thing1") 😄
Couldn't run the lustre/dev.main as esbuild cannot resolve this
import { Thing } from "../build/dev/javascript/app/app.mts";
Yeah, I suppose in theory that just works if I can run this. As JS class instances are just JS objects.
These two files show what I'm attempting to do if anyone is interested
https://github.com/sporto/explore-gleam-lustre/blob/main/src/app.gleam
https://github.com/sporto/explore-gleam-lustre/blob/main/src/thing.ts
So import { Thing } from "../build/dev/javascript/app/app.mts"; has a bad path
If you notice in the error
build/dev/javascript/build/dev/javascript/app/app.mts
All you need to do is ./app.mjs
This is because the file (thing.js) is copied into the build directory
So you'd want import { Thing } from "./app.mjs";
Note that I changed to .mjs instead
Ah, I see, you are running it differently
I was using gleam run -m lustre/dev start
oh don't do the command i was running then
if you're writing lustre do that lustre one
The important bit is that you’re trying to import a .mts but gleam doesnt compile to typescript it compiles to javascript with separate typescript declaration files
Alright progress. In order for esbuild to find the paths they need to be absolute
import { Result, Ok } from "build/dev/javascript/prelude.mjs";
import { Thing } from "build/dev/javascript/app/app.mjs";
you might find this useful: https://github.com/mscharley/gleam-commonmark/commit/06cee0fa93694b4c6419b02047e2d7019561b1aa
this is pretty specific to my project, but it shows where all the files are located and how to bundle things up for both javascript and typescript types
not sure how this approach deals with prelude stuff though. the types definitely work, but they're probably not accessible for import :/
they're not making a library and they're not using esbuild directly