fable-compiler / Fable

F# to JavaScript, TypeScript, Python, Rust and Dart Compiler
http://fable.io/
MIT License
2.93k stars 301 forks source link

Auto-generate implicit string conversion for types with StringEnum Attribute #3107

Open roboz0r opened 2 years ago

roboz0r commented 2 years ago

Description

Suggestion to auto-generate implicit conversion operator for DU's with a StringEnum

Repro code

[<StringEnum>]
type MyType =
| MyString
  with
  static member inline op_Implicit (x: MyType ) : string = !!x // auto-generate this line

Expected and actual results

Often working with API's which expect a string you will create a StringEnum to match suitable values for your project. To use the API you then need to coerce DU back to a string someFunc(string MyString) or someFunc(!!MyString) even though it gets erased anyway. Generating an implicit auto-conversion back to string at relevant call sites seems like an easy change without loss of type safety since the callee expects any string anyway.

alfonsogarciacaro commented 2 years ago

Hi @roboz0r! Your suggestion makes sense but not sure it's going to be easy to implement. Right now Fable doesn't touch F# files at all, this is left to other tools like IDEs or Myriad. Adding this capability to Fable won't be trivial and I assume it would likely conflict with the file watcher.

roboz0r commented 2 years ago

My thought was to somehow tell the compiler that a DU tagged with StringEnum was compatible with string rather than physically inserting static member inline op_Implicit (x: MyType ) : string = !!x in the file. As I think about it more, maybe that's not so simple and would require promoting StringEnum to FSharp.Core to make the main F# compiler aware of it to not generate type errors. If it's a lot of work, it's probably not worth making the change as adding the line is trivial where needed.

alfonsogarciacaro commented 2 years ago

Yes, unfortunately, this is not easily done. There are two main reasons:

  1. Fable doesn't do type checking, this is done by the F# compiler. When we have Fable magic we usually use generic operators to bypass type checking, but we cannot alter type checking directly without modifying the F# compiler.
  2. Even if we could, the IDE would still complain so users would get an error on screen even if the program actually works, which is not very good dev experience.