bevy_mod_js_scripting icon indicating copy to clipboard operation
bevy_mod_js_scripting copied to clipboard

Export TypeScript Definitions For Game Components

Open zicklag opened this issue 3 years ago • 11 comments

It should be possible for us to export TypeScript definitions for all of the types that we can find in the Bevy type registry. That would allow us to give type definitions for all the components you can interact with in scripts.

We may want to come up with a way that you could import the type definition for Vec3 for instance, and then it could contain the full type name in it so that you could use it to extract the ComponentInfo and ComponentId for that type.

This needs some thought, but I think we should be able to make a nice workflow.

zicklag avatar Aug 13 '22 15:08 zicklag

Maybe they could be autogenerated using the static TypeInfo if available https://docs.rs/bevy_reflect/latest/bevy_reflect/enum.TypeInfo.html

jakobhellermann avatar Aug 13 '22 15:08 jakobhellermann

Yeah, that was what I was thinking. And if anything is dynamic it would just map to any.

zicklag avatar Aug 13 '22 15:08 zicklag

It's not possible to associate values with types in typescript, right?

It would be cool if

type Transform = {
  translation: Vec3;
  // ???
};

console.log(Transform.type_name) // the type name we can look up in the type registry 

would work somehow.

jakobhellermann avatar Aug 13 '22 15:08 jakobhellermann

Like an associated constant in rust

jakobhellermann avatar Aug 13 '22 15:08 jakobhellermann

Yeah, unfortunately the closest thing I can find so far is a class with static field:

class Velocity {
  static typeName: string = "breakout::Velocity";
  0: Vec3
}

class Vec3 {
  static typeName: string = "bevy::math::Vec3";
  x: number;
  y: number;
}

This works, but unfortunately because it's an actual class and not done at TypeScript compile time, it requires that we actually import the generated bindings. We can't put them in an "ambient context" like the rest of the types in lib.bevy.d.ts.

That might require that we find a way to mange manage imports in scripts, but I did want to do that anyway, and I don't think it's going to be incredibly difficult, now that I got export rewriting working in #11.

zicklag avatar Aug 13 '22 16:08 zicklag

That alone can't make

world.getResource<Time>();

work, right? Because we have no instance of the type available.

Maybe

function getResource<T>(ty: BevyType<T>) {}

interface Time {
  delta_seconds: number;
}
const Time: BevyType<Time> = { typeName: "..." };


let time = world.getResource(Time);
// Time type is inferred 

I don't know if typescripts type inference is good enough for that, and if it has separate type and value namespaces.

jakobhellermann avatar Aug 13 '22 16:08 jakobhellermann

Update: typescripts inference is strong enough. This works:

type BevyType<T> = { typeName: string; };

type Time = {
    seconds: number,
};
const Time: BevyType<Time> = { typeName: "bevy_core::time::Time" };

function getResource<T>(type: BevyType<T>): T {
    throw new Error();
}

let resource = getResource(Time);
resource.seconds;

jakobhellermann avatar Aug 13 '22 17:08 jakobhellermann

Oh sweet! That's great.

zicklag avatar Aug 13 '22 17:08 zicklag

Exporting all types in a quick and hacky way is pretty easy: https://github.com/jakobhellermann/bevy_reflect_ts_type_export/blob/main/generated/types.ts

And working with typed APIs is super nice: https://github.com/jakobhellermann/bevy_mod_js_scripting/blob/5b2df5e6db55eeb1fade17b56e05d303326d5e9e/assets/scripts/breakout.ts#L12-L23

jakobhellermann avatar Aug 13 '22 20:08 jakobhellermann

TS can just overload two method signatures, and the deno op can deal with either. https://github.com/jakobhellermann/bevy_mod_js_scripting/blob/5b2df5e6db55eeb1fade17b56e05d303326d5e9e/src/runtime/js/index.d.ts#L53-L54

jakobhellermann avatar Aug 13 '22 20:08 jakobhellermann

Great, now we just have to set it up so you can import { Vec3 } from "./types.ts in a script so that you don't have to copy-and-paste the components from types.ts.

I think I'll work on that after finishing #11, which is getting pretty close to working now.

zicklag avatar Aug 14 '22 01:08 zicklag