Releases: ScalablyTyped/Converter
v1.0.0-beta40
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:
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 f514ce0 .
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 7cb11a7
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 baf58e8 .
- @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}}
+ }}}
+ */
+@js.native
+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 28eaaad, 10e2ae1, e94a5f3 and 424fb03
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 21ff172
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:
Currently it stands at 12821 successfully imported libraries, and 92 failing (plus whatever is downstream of those).
Bugfixes
- 6b07292
- 6976cf5
- 4c38c4a
- 46c5867
- aad3cd9
- b47f557
- 2830197
- 36a8eef
- 024a20f
- 07eb5da
- 6d09e70
- 55b1a9d
- 5a7f9b3
- 59ad3ad
- 8cbefd6
- fbe142d
- a3bc60c
- ea716a4
- 41337df
- 2f966b8
- 37a3db3
- a2bdf6c
In total, all these improvements add up to hundreds of newly supported libraries
New Contributors
Full Changelog: v1.0.0-beta39...v1.0.0-beta40
1.0.0-beta39
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 sbt/librarymanagement#399 for details
v1.0.0-beta38
Accumulated bugfixes over the last months. See commit list for details
Contributors:
23 Øyvind Raddum Berg
18 Scala Steward
1 Fabio Pinheiro
1.0.0-beta37
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
- now compiles with
-source:future
- see #364 . The most visible thing is that classes are nowopen
. - fixed a bug which crashed the compiler when compiling
csstype
, which is a dependency of react. The issue was an intersection type withjs.Object
andString
. Fixed in f4451cf - Now requires Scala 3.1.0 in 7856ba7
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
- #355 fixes an issue with calculating erasure of intersection types for scala 2. This is important because failure to do so correctly may lead to ST outputting code with methods with erasure clash.
- ceffbad updates bloop to work with scala 2.13.7
- dea25db avoids resolving names in the global scope when it actually points at a type parameter
- sbt plugin can now coexist with sbt-web-scalajs-bundler . See #387
- static "forwarders" didn't handle varargs correctly, see #394
- react flavours: handle components with names only differing in casing better 906a0ca and a207ce5
Contributors:
30 Øyvind Raddum Berg
11 Scala Steward
2 Hugo van Rijswijk
1 Ingar Abrahamsen
1 nafg
1.0.0-beta36
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:
-@scala.inline
- 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, 88ec013)
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
1.0.0-beta35
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
1.0.0-beta34
Support for Scala 3 (#202, #310)
After months of prep-work (and a few compiler bugs) the converter now works with Scala 3 🥳
React users likely cannot update yet, since neither scalajs-react nor Slinky works with Scala 3 yet.
- If you use scalajs-react you're in luck, because the first milestone of 2.0.0 should be released soon, and ST works well with that, see ScalablyTyped/ScalaJsReactDemos#12.
- If you use Slinky you'll need to wait.
The demo repository is updated, and it'll soon see a style update as well in ScalablyTyped/Demos#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("© <a href="http://osm.org/copyright">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.|
andwith
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
1.0.0-beta33
1.0.0-beta32
- 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 🎆
1.0.0-beta31
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
- aa1a672 fixes incorrect javascript references in some nested structures
Improvements to builders
Set literal members automatically (8c5b59e, 7adc999)
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 (710eff0, 7adc999)
@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 613bc2e
Core improvements
- Improved type qualification (c82fb1c)
- Fix libraries with more than 11k literal strings, like
@expo/vector-icons
(6de2dc9) - Fix libraries where two different literal strings are escaped were escaped into the same type name in Scala 6d5d838
- Output trait instead of type aliases in the presence of vararg functions in some cases (12c0006)
- 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
- ]
+@js.native
+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 (2513f0f)
- 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 (a4273b1)
Documentation
Added Working with objects
Contributors:
26 Øyvind Raddum Berg
11 Scala Steward
1 povder