Skip to content
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

[Unity] Bug: Number overloads #1871

Open
3 tasks done
raad-genies opened this issue Oct 21, 2024 · 6 comments
Open
3 tasks done

[Unity] Bug: Number overloads #1871

raad-genies opened this issue Oct 21, 2024 · 6 comments
Assignees
Labels
bug Something isn't working Unity

Comments

@raad-genies
Copy link

前置阅读 | Pre-reading

Puer的版本 | Puer Version

Latest

Unity的版本 | Unity Version

2022.3

发生在哪个平台 | Platform

Editor(mac)

错误信息 | Error Message

Not an error but more of an issue with how number overloads work. In the case of Random.Range Puerts currently has no way of distinguishing between the float and the int overloads which results in float always passing since number can always be a float.

Also any tips around how to create the same overload in the TS side would be great. Branding can work but then its essentially a new type and can't really just say var x : float = 9 for example.

问题重现 | Bug reproduce

Bind Random.Range and try to call it with decimals or without.

@raad-genies raad-genies added bug Something isn't working Unity labels Oct 21, 2024
@chexiongsheng
Copy link
Collaborator

Due to the differences in the richness of types between C# and TypeScript/JavaScript, multiple C# types may map to a single JavaScript type. A suggested solution is to encapsulate the C# API with different names to avoid overloading. For example, instead of having Foo(float), Foo(int), and Foo(short), you can encapsulate them as Foo_float(float), Foo_Int(int), and Foo_short(short).

@raad-genies
Copy link
Author

@chexiongsheng Is it possible to actually use branded types in TS defined globally like

 declare type float = number & { [floatBrand]: void };
 declare type int = number & { [intBrand]: void };

And include the alias info in the js call info? This would allow us to at least do type checking without having to resort to weird overload naming specially if you have some APIs that are engine specific.

@chexiongsheng
Copy link
Collaborator

What are the declarations of floatBrand and intBrand?

@raad-genies
Copy link
Author

Unique symbol

@chexiongsheng
Copy link
Collaborator

chexiongsheng commented Oct 25, 2024

How to call these apis? below code compile fail: error TS2345: Argument of type 'number' is not assignable to parameter of type 'int'.
Type 'number' is not assignable to type '{ [intBrand]: void; }'.

declare type float = number & { [floatBrand]: void };
declare type int = number & { [intBrand]: void };

function foo(a:int) {

}
foo(100);

Moreover, even if TypeScript distinguishes the types, since only JavaScript is available at runtime, you still won't be able to select the overload you want.

Not all overloads require renaming; only a small number of APIs that distinguish between overload types that happen to map to a specific TypeScript type need to be renamed.

@raad-genies
Copy link
Author

Yeah no worries. I followed a different route to fix this since we have our own compiler, the approach we're using allows us to replace overload calls by inferring the type based on literal or if the type matches this way it's seamless to devs. The other approach I was thinking of is just being able to pass aliases in the js call info.

Appreciate the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Unity
Projects
None yet
Development

No branches or pull requests

2 participants