question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Problems converting LocalizedStrings.d.ts

See original GitHub issue

We tried to create bindings for https://github.com/stefalda/react-localization/blob/master/lib/LocalizedStrings.d.ts

And get the following results: image

Any idea what happened? Also we tried to fix the error by replacing JSX.Element with React.ReactElement and then other errors appear which look like F# syntax errors.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
MangelMaximecommented, Jul 19, 2018

I have been able to make the library work with Fable. The react_localization.fs can probably still need some clean up because I was just focus on getting thing working 😃.

react_localization.fs

// ts2fable 0.6.1
module rec ReactLocalization
open System
open Fable.Core
open Fable.Import.JS

let [<Import("*","react-localization")>] ``react-localization``: React_localization.IExports = jsNative

module React_localization =

    type [<AllowNullLiteral>] IExports =
        abstract LocalizedStringsFactory: LocalizedStringsFactoryStatic
        abstract LocalizedStrings: LocalizedStringsFactoryStatic

    type Formatted =
        // U3<float, string, JSX.Element>
        U2<float, string>

    [<RequireQualifiedAccess; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
    module Formatted =
        // let ofFloat v: Formatted = v |> U3.Case1
        // let isFloat (v: Formatted) = match v with U3.Case1 _ -> true | _ -> false
        // let asFloat (v: Formatted) = match v with U3.Case1 o -> Some o | _ -> None
        // let ofString v: Formatted = v |> U3.Case2
        // let isString (v: Formatted) = match v with U3.Case2 _ -> true | _ -> false
        // let asString (v: Formatted) = match v with U3.Case2 o -> Some o | _ -> None
        // let ofJSX.Element v: Formatted = v |> U3.Case3
        // let isJSX.Element (v: Formatted) = match v with U3.Case3 _ -> true | _ -> false
        // let asJSX.Element (v: Formatted) = match v with U3.Case3 o -> Some o | _ -> None
        let ofFloat v: Formatted = v |> U2.Case1
        let isFloat (v: Formatted) = match v with U2.Case1 _ -> true | _ -> false
        let asFloat (v: Formatted) = match v with U2.Case1 o -> Some o | _ -> None
        let ofString v: Formatted = v |> U2.Case2
        let isString (v: Formatted) = match v with U2.Case2 _ -> true | _ -> false
        let asString (v: Formatted) = match v with U2.Case2 o -> Some o | _ -> None

    type [<AllowNullLiteral>] FormatObject<'U> =
        [<Emit "$0[$1]{{=$2}}">] abstract Item: key: string -> 'U with get, set

    type [<AllowNullLiteral>] GlobalStrings<'T> =
        [<Emit "$0[$1]{{=$2}}">] abstract Item: language: string -> 'T with get, set

    type [<AllowNullLiteral>] LocalizedStrings<'T> =
        /// <summary>Can be used from ouside the class to force a particular language
        /// indipendently from the interface one</summary>
        /// <param name="language"></param>
        abstract setLanguage: language: string -> unit
        /// The current language displayed (could differ from the interface language
        /// if it has been forced manually and a matching translation has been found)
        abstract getLanguage: unit -> string
        /// The current interface language (could differ from the language displayed)
        abstract getInterfaceLanguage: unit -> string
        /// Format the passed string replacing the numbered placeholders
        /// i.e. I'd like some {0} and {1}, or just {0}
        /// Use example:
        ///    strings.formatString(strings.question, strings.bread, strings.butter)
        abstract formatString: str: string * [<ParamArray>] values: Array<U2<'T, FormatObject<'T>>> -> U2<Array<U2<string, 'T>>, string>
        /// Return an array containing the available languages passed as props in the constructor
        abstract getAvailableLanguages: unit -> ResizeArray<string>
        /// <summary>Return a string with the passed key in a different language</summary>
        /// <param name="key"></param>
        /// <param name="language"></param>
        abstract getString: key: string * language: string -> string
        [<Emit("$0.getString($1, $2)")>]
        abstract getStringNested: key: string * language: string -> LocalizedStrings<'T>
        /// <summary>Replace the NamedLocalization object without reinstantiating the object</summary>
        /// <param name="props"></param>
        abstract setContent: props: 'T option -> unit
        [<Emit("$0")>]
        abstract ref : 'T

    type [<AllowNullLiteral>] LocalizedStringsFactoryStatic =
        [<Emit "new $0($1...)">] abstract Create: props: GlobalStrings<'T> -> LocalizedStrings<'T>

App.fs

module Client

open Fable.Core
open Fable.Core.JsInterop
open Fable.Import
open ReactLocalization

// We use a POJO type so it's erased at compilation
[<Pojo>]
type Content =
    { SignIn : string
      Logout : string }

// Define the language strings
let globals = jsOptions<React_localization.GlobalStrings<Content>>(fun o ->
    o.Item("fr") <-
        { SignIn = "Connexion"
          Logout = "Déconnexion" }
    o.Item("en") <-
        { SignIn = "Sign-in"
          Logout = "Logout" }
)

let localizedStrings : React_localization.LocalizedStringsFactoryStatic = import "default" "react-localization"

let strings = localizedStrings.Create(globals)

Browser.console.log(strings.getString("SignIn", "fr"))
Browser.console.log(strings.getString("SignIn", "en"))
Browser.console.log(strings.getString("Logout", "fr"))
Browser.console.log(strings.getString("Logout", "en"))

// From here we are using custom binding to get benefit of intellisense
Browser.console.log(strings.ref.Logout)
strings.setLanguage("en")
Browser.console.log(strings.ref.Logout)

Here is the result:

capture d ecran 2018-07-19 a 14 23 00
1reaction
MangelMaximecommented, Jul 19, 2018

@matthid In general, when you are using Elmish in your application and want to use React libraries.

The recommanded way is to write the “special” bindings to keep the same DSL and use functional style. We don’t have yet a project to automate this process.

For example, in my app we need to use react-leaflet and the binding can be found here

As you can see it have nothing to look with what ts2fable output.


In the case of LocalizedStrings.d.ts I don’t think it’s needed because it isn’t providing components for you to use.

The JSX.Element case correspond to:

 // React components can be used as placeholder values! Useful when using links or customizing style
  strings.formatString(strings.onlyForMembers, <a href="http://login.com">{strings.login}</a>)
  strings.formatString(strings.iAmText, <b>{strings.bold}</b>)

And I don’t think, you will use this synthax in your project. I think you could remove the JSX.Element references in the generated binding.

I think you can use the library to retrieve the string and directly use it in your views.

Pseudo code:


let strings : LocalizedStringsFactory = LocalizedStringsFactoryStatic.Create((* here you pass the records for the strings*))

let view model dispatch =
    p [ ]
        [ str (strings.formatString(strings.question, strings.bread, strings.butter)]
Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript: .d.ts file not recognized
There might be two issues here: 1.) You need to augment Window interface in global scope. Either remove all import / export keywords...
Read more >
No localization from Main.Storyboard (English)
The problem I am facing is that all texts, titles, labels to be translated automatically in the Storyboard are not. At the same...
Read more >
Localize SharePoint Framework client-side web parts
Broaden the appeal of your web part by localizing it for different languages spoken by SharePoint users all over the world.
Read more >
Changing the localized strings — Seminar Manager 3.3 ...
Changing the localized strings¶. You can change most of the localized strings that are used on the front end and for the e-mails....
Read more >
Over the Air (Strings)
If using a distribution for iOS and Android, placeholders for the two formats are automatically converted. Fallbacks. If language fallbacks are set in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found