ScalablyTyped Converter Versions Save

Typescript to Scala.js converter

v1.0.0-beta40

1 year ago

This is a packed release 🚀 , with bug fixes going back months as well as significant encoding changes.

Supports sbt 1.8.x only

Due to the scala-xml situation only sbt 1.8.x is supported now.

Note that due to a bug in scalajs-bundler you'll also have to upgrade it to 0.21.1 if you use it.

Predictable module names

Read about it here #485 , it's an effort to make the encoding more transparent.

Basically it will require you to go through your code base and perform this maneuver:

Renaming module names

If you're not ready to do it right away, add stShortModuleNames := true (for sbt plugin) and --shortModuleNames for CLI. This will keep the old behaviour.

Note that it's expected that windows users will face some problems after this change, since paths will be longer on average. Some of the other changes in the release are motivated by working towards shorter source and class file names.

No longer rewrite types in inheritance to js.Promise

Sorry, but it's impossible to do it in inheritance clauses, so that was taken out. Instead references to std.Promise is generated, and you get syntax for it. Implemented in f514ce01 .

val p: std.Promise[Int] = ???
val p2: js.Promise = p.toPromise
val p3: Future = p.toFuture

Changes to number "fake literals"

if you references things inside ...libNumbers you'll now have to reach into ...libDoubles and ...libInts instead. Some unrepresentable or very long literals are now widened to String or Double. Fake literals end up as java class files, and they should ideally not be too long given windows' max path length.

Implemented in 7cb11a78

Support for package exports

This is a newish concept for exposing javascript modules on names which do not match file path, it also works for hiding modules inside a package. This enables multiple "big" libraries to work much better with ST, primarily firebase.

Implemented in #367

Do not output abstract classes

The functionality in ST which calculates for instance which methods should be added to "complete" a class given that it extends from interfaces where fields and methods are left without an implementation didn't really work with abstract classes. These hierarchies can be awfully deep, and there are loads of edge cases.

Given that this would require difficult changes to ST to fix, and since this functionality is so rarely used in Typescript, the entire concept is just replaced by a comment for now. The user can then do the right thing and implement what's missing. Implemented in baf58e88 .

-  @JSImport("aws-sdk/lib/config_service_placeholders", "ConfigurationServicePlaceholders")
-  @js.native
-  abstract class ConfigurationServicePlaceholders () extends StObject {
+  /* note: abstract class */ @JSImport("aws-sdk/lib/config_service_placeholders", "ConfigurationServicePlaceholders")
+  @js.native
+  open class ConfigurationServicePlaceholders () extends StObject {

Better documentation for untranslatable types

-type Proxify[T] = /* import warning: importer.ImportType#apply c Unsupported type mapping: 
-{[ P in keyof T ]: {get (): T[P], set (v : T[P]): void}}
-  */ typings.typeMappings.typeMappingsStrings.Proxify & TopLevel[Any]
+/** NOTE: Mapped type definitions are impossible to translate to Scala.
+  * See https://www.typescriptlang.org/docs/handbook/2/mapped-types.html for an intro.
+  * You'll have to cast your way around this structure, unfortunately. 
+  * TS definition: {{{
+  {[ P in keyof T ]: {get (): T[P], set (v : T[P]): void}}
+  }}}
+  */
[email protected]
+trait Proxify[T] extends StObject

Better handling of conditional types

These are also untranslatable. However, in conditional types there is frequently some base case, which often is useful from Scala.

With approximation

As such there is functionality to pick out this base case as an approximation. Note that the approximation part is not new per se, but it's improved.

/**
  * Exclude from T those types that are assignable to U
  */
/** NOTE: Conditional type definitions are impossible to translate to Scala.
  * See https://www.typescriptlang.org/docs/handbook/2/conditional-types.html for an intro.
  * This RHS of the type alias is guess work. You should cast if it's not correct in your case.
  * TS definition: {{{
  T extends U ? never : T
  }}}
  */
type Exclude[T, U] = T

Without approximation

/** NOTE: Conditional type definitions are impossible to translate to Scala.
  * See https://www.typescriptlang.org/docs/handbook/2/conditional-types.html for an intro.
  * You'll have to cast your way around this structure, unfortunately.
  * TS definition: {{{
  R extends react.react.Reducer<any, infer A> ? A : never
  }}}
  */
@js.native
trait ReducerAction[R /* <: Reducer[Any, Any] */] extends StObject

Implemented in 28eaaada, 10e2ae1a, e94a5f3c and 424fb031

Destructured parameters get shorter names

Given typescript code

export declare const rectWithPoints: ({ x: x1, y: y1 }: Coordinate, { x: x2, y: y2 }: Coordinate) => {
    x: number;
    y: number;
    width: number;
    height: number;
};

-  inline def rectWithPoints(hasX1Y1: Coordinate, hasX2Y2: Coordinate): Height = (^.asInstanceOf[js.Dynamic].applyDynamic("rectWithPoints")(hasX1Y1.asInstanceOf[js.Any], hasX2Y2.asInstanceOf[js.Any])).asInstanceOf[Height]

+  inline def rectWithPoints(param0: Coordinate, param1: Coordinate): Height = (^.asInstanceOf[js.Dynamic].applyDynamic("rectWithPoints")(param0.asInstanceOf[js.Any], param1.asInstanceOf[js.Any])).asInstanceOf[Height]

This is because the names could become unwieldy long, and would in some cases end up names of java class files. Implemented in 21ff172c

Migration from CircleCI to Github Actions and improved Windows support

ST is now built in CI on linux, mac and windows. To get the tests running, a bunch of improvements to consistency (= ST always outputs exactly the same code, and digests it to the same hash) was needed.

This will greatly benefit anyone using windows, as your builds now have the same digest as your friends / colleagues. It will also benefit anyone wanting to contribute to ST from windows, as tests will now run clean on your machine.

Implemented in #500.

Upgraded "community build"

While not user-facing, it's also significant that the Distribution build is ran every night, with all the newest versions of libraries. Before libraries were generally out of date, because it's very difficult to make npm or yarn upgrade 10k packages. This was fixed in #477.

This way, the effect of a commit on master can be seen clearly:

Screenshot 2022-11-16 at 19 40 34

Currently it stands at 12821 successfully imported libraries, and 92 failing (plus whatever is downstream of those).

Bugfixes

  • 6b072925
  • 6976cf52
  • 4c38c4aa
  • 46c5867c
  • aad3cd92
  • b47f557f
  • 28301974
  • 36a8eef2
  • 024a20f7
  • 07eb5da8
  • 6d09e70c
  • 55b1a9df
  • 5a7f9b35
  • 59ad3ad4
  • 8cbefd64
  • fbe142db
  • a3bc60c2
  • ea716a40
  • 41337df7
  • 2f966b81
  • 37a3db3c
  • a2bdf6ce

In total, all these improvements add up to hundreds of newly supported libraries

New Contributors

Full Changelog: https://github.com/ScalablyTyped/Converter/compare/v1.0.0-beta39...v1.0.0-beta40

v1.0.0-beta39

1 year ago

This bumps the sbt version necessary to 1.7.x. This was necessary since the vulnerable okhttp 3 library, which used to be shipped with sbt, was used in the ScalablyTyped sbt plugin. See https://github.com/sbt/librarymanagement/pull/399 for details

v1.0.0-beta38

1 year ago

Full changelog

Accumulated bugfixes over the last months. See commit list for details

Contributors:

23  Øyvind Raddum Berg
18  Scala Steward
 1  Fabio Pinheiro
 
 

v1.0.0-beta37

2 years ago

Full changelog

Breaking changes

Update to scala.js 1.8.0

While ST should work with older versions, there are no tests to ensure it works. For that reason it's strongly recommended to stay current.

Update to scala-js-dom 2.0.0

Upgrading to scala-js-dom 2.0.0 requires migration, see release notes. Note that ST only supports one version of scala-js-dom, so to use 1.0.0-beta37 you need to upgrade.

Done in #377

Update to scalajs-react 2.0.0

If you use scalajs-react it has also seen a major release, so your code may require some migration for that as well. Again see release notes

Note again that ST only supports one version of scalajs-react, so to use 1.0.0-beta37 you need to upgrade.

On the bright side you get Scala 3 support. Have a look at the demo projects which are ported to scala 3, including new syntax.

Done in #326

Any instead of js.Any

See #351 . This might require some tweaks to your code, but it should just be changing the latter to the former. Usage of js.Any remains in some places, like when interacting with js.Dynamic.

Types from scalajs-library

If you use stUseScalaJsDom := false (not default) some types are now rewritten from std to types in scalajs-library, for instance js.Error and typed arrays. See #372 .

Other changes

Improved Scala 3 support

Slinky 0.7.0

If you use the slinky flavour, you'll need to update. There shouldn't be any migration required. ST will now use the Scala 3 artifact of slinky-web for Scala 3, and will generate working code. However, if you want to upgrade keep in mind that all the @react syntax is missing in Scala 3 so far.

Enable support for sbt 1.6.x

This is fairly untested, but it seemed to be binary compatible with 1.5.x .

Comment which ecmascript standard methods are from in std standard library

For now these are just comments. If they are useful for tooling, perhaps they could become annotations down the line.

@js.native
trait Map[K, V] extends StObject {
  
  /* standard es2015.collection */
  def clear(): Unit = js.native
  
  /**
    * Returns an iterable of key, value pairs for every entry in the map.
    */
  /* standard es2015.iterable */
  def entries(): IterableIterator[js.Tuple2[K, V]] = js.native
  
  /* standard es2015.collection */
  def forEach(callbackfn: js.Function3[/* value */ V, /* key */ K, /* map */ Map[K, V], Unit]): Unit = js.native
  def forEach(callbackfn: js.Function3[/* value */ V, /* key */ K, /* map */ Map[K, V], Unit], thisArg: js.Any): Unit = js.native
  
  /** Returns an iterable of entries in the map. */
  /* standard es2015.iterable */
  @JSName(js.Symbol.iterator)
  var iterator: js.Function0[IterableIterator[js.Tuple2[K, V]]] = js.native
  
  /* standard es2015.symbol.wellknown */
  @JSName(js.Symbol.toStringTag)
  val toStringTag: java.lang.String = js.native
  }

Bugfixes

Contributors:

30  Øyvind Raddum Berg
11  Scala Steward
 2  Hugo van Rijswijk
 1  Ingar Abrahamsen
 1  nafg

v1.0.0-beta36

2 years ago

Full changelog

Enable private facades (#332)

Especially useful for generating libraries, you can now mark all the generated code as private within a package, see docs for stPrivateWithin

It'll look like this:

package mylib.internal.baz.materialUi

import japgolly.scalajs.react.raw.React.Component
import org.scalablytyped.runtime.StObject
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSGlobalScope, JSGlobal, JSImport, JSName, JSBracketAccess}

private[internal] object MaterialUI {
...
}

Use extension and inline for Scala 3 code (#335)

This is just syntactic, but really does clean up code:

[email protected]
-    implicit class APIVersionsMutableBuilder[Self <: APIVersions] (val x: Self) extends AnyVal {
-
-      @scala.inline
-      def setApiVersion(value: latest | String): Self = StObject.set(x, "apiVersion", value.asInstanceOf[js.Any])
+   extension [Self <: APIVersions](x: Self) {
+
+      inline def setApiVersion(value: latest | String): Self = StObject.set(x, "apiVersion", value.asInstanceOf[js.Any])

Add support for export namespace as

Quite a few libraries were missing the globally available version of the typings because this typescript construct was not implemented.

Support for generating typings for devDependencies as well (#339, 88ec013bd6d8ba9eaa58ec127d273396dd91dbf4)

This needs to be enabled by stIncludeDev

Version bumps

Drops support for sbt 1.4 and only allows 1.5, Also upgrades to scala-js-dom 1.2, Scala.js 1.7.0

Encoding change: keep parameters of unions of string literals grouped

The translation of method definition in ST relies on splitting methods into more methods on union types. Given this:

export const foo = (bar: 'a' | ' b' | number) => number

This used to be translated like this:

def foo_a(bar: a): Double // using the fake literal types encoding
def foo_b(bar: b): Double
def foo(bar: Double): Double

Now it'll be translated to this instead:

def foo(bar: a | b): Double // using the fake literal types encoding
def foo(bar: Double): Double

This is somewhat experimental, and is meant to be a step on the way towards cleaner method signatures and true literal types.

Remove more duplicated types

ST has some logic for deduplicating types which are exported and reexported between modules by only keeping the original version, this is done to avoid ambiguity errors and to reduce the total number of generated types. Some re-exported types slipped through the net, and are now not generated anymore. If this affects you you should be able to delete the import and import whatever the IDE suggests instead.

Contributors:

32  Øyvind Raddum Berg
 2  Scala Steward
 1  Alexis Hernandez
 1  Arman Bilge

v1.0.0-beta35

2 years ago

Full changelog

Generate Non-native JS types (@ScalaJSDefined) by default for Scala 3

See Scala.js documentation for details. This has been possible to enable with stEnableScalaJsDefined, but it has been disabled because compilation is very very slow with Scala 2.x. For Scala 3 this is now enabled for all libraries by default.

Bugfixes

Quite a few see full changelog for details

v1.0.0-beta34

2 years ago

Full changelog

Support for Scala 3 (#202, #310)

After months of prep-work (and a few compiler bugs) the converter now works with Scala 3 :partying_face:

React users likely cannot update yet, since neither scalajs-react nor Slinky works with Scala 3 yet.

The demo repository is updated, and it'll soon see a style update as well in https://github.com/ScalablyTyped/Demos/pull/25 .

Note

Libraries with more than 6000 files can only be compiled with Scala 3.0.1 and up, which is due for release any day now. You'll see a StackOverflowError if this affects you.

Encoding changes

No longer generate wildcards (Scala 2 and 3)

In a lot of places js.Any was rewritten to _ to make some patterns a bit smoother, primarily to pretend like types were covariant.

This is an example of generated before/after

@js.native
trait RefProps extends StObject {
  var children: Element = js.native
-  var innerRef: Ref[_] = js.native  
+  var innerRef: Ref[js.Any] = js.native
}

Before you could do this:

val ref: Ref[Foo] = ???
val refProps: RefProps = ???
refProps.innerRef = ref

And after you'll have to cast to make the last statement work

refProps.innerRef = ref.asInstanceOf[Ref[js.Any]]

This is clearly unfortunate, but existential types are sufficiently different (and limited) in Scala 3 that no path forward was found here. More work could be done in this direction, however.

New implementation of erasure for intersection and union types (Scala 3)

This is not user facing, but it means that the set of generated methods will vary slightly in the presence of many overloads.

Regression in react flavours (Scala 2 and 3)

A type parameter for reference had to be added to (the implicitly called) StBuildingComponent.make for Scala 3. Some react components have type parameters, and in some cases those will be inferred to be Nothing. When that happens an explicit .build is needed with Scala 2.

// part of a generated component which is polymorphic both in props and element
object TileLayer {
  def apply[P /* <: TileLayerProps */, E /* <: TileLayer_ */](p: P): Builder[P, E] = new Builder[P, E](js.Array(this.component, p.asInstanceOf[js.Any]))

// use component. unless explicitly set, `E` ends up as `Nothing`
TileLayer(
  TileLayerProps(url = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
    .setAttribution("&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors")
),

Now you'll need to say TileLayer(...).build. This should be fixed in a future release

Difference in code between Scala 2 and 3

The generated code is 99% the same across scala versions after this change, except for

  • package members are moved from a package object to top-level.
  • the real union and intersection types are used instead of js.| and with

This diff shows typical differences:

-package typings
+package typings.node
 
 import org.scalablytyped.runtime.StObject
 import scala.scalajs.js
-import scala.scalajs.js.`|`
 import scala.scalajs.js.annotation.{JSGlobalScope, JSGlobal, JSImport, JSName, JSBracketAccess}
 
-package object node {
   
   type Foo = typings.node.NodeBuffer | String
-}

Contributors:

26  Øyvind Raddum Berg
 5  Scala Steward

v1.0.0-beta33

2 years ago

Full changelog

  • Hotfix to enable parsing typescript 4.3 standard library #320
  • Bugfix for minimization after recent encoding changes #312
  • Be more forgiving in the presence of missing dependencies dd3dd10
  • More prep for Scala 3 support #291

Contributors:

11  Scala Steward
 5  Øyvind Raddum Berg

v1.0.0-beta32

3 years ago

Full changelog

  • Adds support for sbt 1.5.x along with 1.4.0
  • Reintroduces shaded circe dependency, which is now published to maven central as well. This completes the migration away from bintray :fireworks:

v1.0.0-beta31

3 years ago

Full changelog

Now published to maven central

Bintray is shutting down, and that had been used extensively for ScalablyTyped. Some details in #262 , but most importantly:

  • the sbt plugin no longer uses a forked version of circe. As such you're likely to experience binary incompatibilities in sbt if you add many other plugins. Note that this is not ScalablyTyped's "fault", but it'll be fixed somehow for beta32 anyway. For now if you see ClassDefNotFoundError or similar in sbt you're affected. More details in #271
  • you no longer need to supply a resolver in plugins.sbt.
  • unless you want to use snapshots, in which case use this resolvers += MavenRepository("sonatype-s01-snapshots", "https://s01.oss.sonatype.org/content/repositories/snapshots"). All master builds publish snapshots
  • the CLI has lost the ability to publish directly in #272 . If you depended on this functionality you're encouraged to get in touch if you want to contribute a new solution. If you revive the old commit and integrate with a new library to publish jars it's probably not very hard. Also get in touch on gitter to discuss other workarounds

Fallout from the encoding change in beta30

  • #255 fixes a rare name collision
  • #258 invents a receiver object in some cases to correctly set this
  • #276 reimplements minimization on top of new encoding
  • aa1a6725c1149591b10555122f5751220773879b fixes incorrect javascript references in some nested structures

Improvements to builders

Set literal members automatically (8c5b59eb, 7adc999f)

  object RadioProps {
    @scala.inline
-    def apply(name: String, `type`: radio): RadioProps = {
-      val __obj = js.Dynamic.literal(name = name.asInstanceOf[js.Any])
-      __obj.updateDynamic("type")(`type`.asInstanceOf[js.Any])
+    def apply(name: String): RadioProps = {
+      val __obj = js.Dynamic.literal(name = name.asInstanceOf[js.Any])
+      __obj.updateDynamic("type")("radio")
      __obj.asInstanceOf[RadioProps]
    }        

Correctly initialize T | Null members (710eff04, 7adc999f)

  @js.native
  trait ReactElement extends StObject {
    var key: Key | Null = js.native
    var props: js.Any = js.native
    var `type`: String | ComponentClassP[js.Object] | SFC[_] = js.native
  }
  object ReactElement {
    @scala.inline
    def apply(props: js.Any, `type`: String | ComponentClassP[js.Object] | SFC[_]): Element = {
-      val __obj = js.Dynamic.literal(props = props.asInstanceOf[js.Any])
+      val __obj = js.Dynamic.literal(props = props.asInstanceOf[js.Any], key = null)
      __obj.updateDynamic("type")(`type`.asInstanceOf[js.Any])
      __obj.asInstanceOf[Element]
    }

Improvements to react flavours

  • inherits builder improvements
  • detect components exported at top-level of commonjs library 613bc2e5

Core improvements

  • Improved type qualification (c82fb1cd)
  • Fix libraries with more than 11k literal strings, like @expo/vector-icons (6de2dc97)
  • Fix libraries where two different literal strings are escaped were escaped into the same type name in Scala 6d5d8384
  • Output trait instead of type aliases in the presence of vararg functions in some cases (12c00069)
-  type DOMFactory[P /* <: typingsJapgolly.react.mod.DOMAttributes[T] */, T /* <: org.scalajs.dom.raw.Element */] = js.Function2[
-    /* props */ js.UndefOr[(typingsJapgolly.react.mod.ClassAttributes[T] with P) | scala.Null], 
-    /* repeated */ japgolly.scalajs.react.raw.React.Node, 
-    japgolly.scalajs.react.raw.React.DomElement
-  ]
  
[email protected]
+trait DOMFactory[P /* <: DOMAttributes[T] */, T /* <: Element */] extends StObject {
+  
+  def apply(props: ClassAttributes[T] with P, children: Node*): DomElement = js.native
+  def apply(props: js.UndefOr[scala.Nothing], children: Node*): DomElement = js.native
+  def apply(props: Null, children: Node*): DomElement = js.native
+}
  • Parser: Be more flexible when parsing destructured parameters (2513f0fc)
  • Parser: Support for labeled tuple elements (#279)
  • Don't fail import when we come across a type parameter that has not been provided. This comes up mainly with mismatched versions, and while it's definitely not a good thing it's also very difficult to understand, diagnose and fix for users. So in the name of convenience let's say it's better to output slightly wrong than nothing at all (a4273b18)

Documentation

Added Working with objects

Contributors:

26  Øyvind Raddum Berg
11  Scala Steward
 1  povder