This repo is no longer maintained. For a newer version supporting a more recent version of UI5, see neoprincie's fork:
This Repo Is No Longer Maintained
For a newer version supporting a more recent version of UI5, see https://github.com/neoprincie/ui5ts.
A simple adapter to develop SAPUI5 and OpenUI5 applications using TypeScript and ES2015 modules/classes
0.3.2 - Handle some UI5 API errors in the Docs, when method with names like getSomething has void
as return type. It is being replaced by any
now.
0.3.1 - Just fixed an error in this README instructions.
0.3.0 - Create definitions for more than one version of UI5 (just 1.46 and 1.48 for now). Published in https://github.com/lmcarreiro/ui5-typescript-definitions too. Be carefull, now that there is these definitions inside the package and I have plans to make these definitions better (normally replacing an any
type with a more specific one), almost all new versions from now on may be a breaking change.
0.2.0 - Create my own UI5 definitions generator, because the available ones didn't fit my needs (you can still use another, just set it up in your tsconfig.json
).
0.1.* - Generated exports files for all namespace sap.* objects, to make possible import these objects without creating a single <object>.d.ts
for each imported object.
0.0.* - Just a draft.
It is very simple, make it work with only 4 steps:
<class-name>.js
to a <class-name>.ts
Check this Master-Detail example app https://github.com/lmcarreiro/ui5-typescript-example that is already working with ui5+typescript.
npm install @types/jquery --save-dev
npm install typescript --save-dev
npm install ui5ts --save
Put a reference to the ui5ts.js
script in your index.html
file using a script tag <script src="node_modules/ui5ts/ui5ts.js" type="text/javascript"></script>
between the sap-ui-core.js
script tag and the sap.ui.getCore().attachInit()
call:
...
<!-- Bootstrapping UI5 -->
<script id="sap-ui-bootstrap" src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" ... ></script>
+ <!-- Convert typescript generated modules/classes into ui5 modules/classes -->
+ <script type="text/javascript" src="node_modules/ui5ts/ui5ts.js"></script>
<script>
sap.ui.getCore().attachInit(function () { ... });
</script>
...
"amd"
true
(just to avoid typescript warning/error)
"./"
(your project root, if you change this value, you need to change the paths too)
{ ... }
(your paths, relative to your baseUrl, check the example bellow)
["node_modules/ui5ts/ui5ts.d.ts", "node_modules/ui5ts/ui5-types/1.48/sap.d.ts", "node_modules/ui5ts/ui5-types/1.48/jQuery.d.ts", ...]
Example of tsconfig.json
file:
{
"compilerOptions": {
"target": "es5",
"module": "amd",
"experimentalDecorators": true,
"alwaysStrict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"sourceMap": true,
"baseUrl": "./",
"paths": {
"your/app/namespace/*": [ "./src/*" ],
"sap/*": [ "./node_modules/ui5ts/exports/sap/*" ]
}
},
"files": [
"node_modules/ui5ts/ui5ts.d.ts",
"node_modules/ui5ts/ui5-types/1.48/sap.d.ts",
"node_modules/ui5ts/ui5-types/1.48/jQuery.d.ts"
],
"include": [
"src/**/*",
"node_modules/@types"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
<class-name>.js
to a <class-name>.ts
sap.ui.define([
"sap/ui/core/UIComponent",
"typescript/example/ui5app/model/models"
], function (UIComponent, models) {
"use strict";
return UIComponent.extend("typescript.example.ui5app.Component", {
metadata: {
manifest: "json"
},
init: function () {
// set the device model
this.setModel(models.createDeviceModel(), "device");
// call the base component's init function and create the App view
UIComponent.prototype.init.call(this);
// create the views based on the url/hash
this.getRouter().initialize();
}
});
});
import UIComponent from "sap/ui/core/UIComponent";
import models from "typescript/example/ui5app/model/models";
@UI5("typescript.example.ui5app.Component")
export default class Component extends UIComponent
{
public static metadata: any = {
manifest : "json"
};
public init(): void {
// set the device model
this.setModel(models.createDeviceModel(), "device");
// call the base component's init function and create the App view
super.init();
// create the views based on the url/hash
this.getRouter().initialize();
}
}
@UI5("your.full.namespace.ClassName")
, this decorator parameter will be passed to BaseClass.extend("your.full.namespace.ClassName", { ... });
call at runtime.static
import
statements must be the same as it would be if you were using sap.ui.define()
function. The TypeScript compiler will generate an AMD module with a define()
call with these paths, and the define()
function that ui5ts overrides will call the real sap.ui.define()
function. This is the way that ui5ts works.your/app/namespace/is/too/big
, you don't need to have all this levels of directories in your physical project structure, you can create a virtual mapping using the tsconfig.json
configuration option paths
(see it in the common problems bellow).Problem: Doesn't find the @UI5 decorator:
...
// error TS2304: Cannot find name 'UI5'.
@UI5("your.full.namespace.ClassName")
export default class Component extends UIComponent {
...
Solution: Make sure you have the ui5ts.d.ts referenced in your tsconfig.json
...
"files": [
...,
+ "node_modules/ui5ts/ui5ts.d.ts"
],
...
Problem: Doesn't find your own *.ts
class:
...
// error TS2307: Cannot find module 'your/app/namespace/folder/ClassName'.
import ClassName from "your/app/namespace/folder/ClassName";
...
Solution: Make sure you have the path of your namespace root in the tsconfig.json
and if it match with your application startup in the index.html
...
"compilerOptions": {
...
"baseUrl": "./",
"paths": {
...
+ "your/app/namespace/*": [ "./src/*" ]
}
...
...
sap.ui.getCore().attachInit(function () {
sap.ui.require(["sap/m/Shell", "sap/ui/core/ComponentContainer"], function (Shell, ComponentContainer) {
new Shell({
app: new ComponentContainer({
height : "100%",
+ name : "your.app.namespace"
})
}).placeAt("content");
});
});
...
Problem: Doesn't find your own *.js
class:
...
// error TS2307: Cannot find module 'your/app/namespace/folder/ClassName'.
import ClassName from "your/app/namespace/folder/ClassName";
...
Solution: Create a corresponding *.d.ts
of your *.js
class or forget about it. You can live with this error and the app will still work. Even if you allow the TypeScript compiler to accept *.js
modules, it will not recognize it as a AMD module, since you declare it using sap.ui.define()
instead of define()
.
Problem: Doesn't find a class in sap.* namespace:
...
// error TS2307: Cannot find module 'sap/ui/core/UIComponent'.
import UIComponent from "sap/ui/core/UIComponent";
...
Solution: Make sure you have mapped the ui5ts exports folder in your paths of the tsconfig.json
:
...
"compilerOptions": {
...
"baseUrl": "./",
"paths": {
...
+ "sap/*": [ "./node_modules/ui5ts/exports/sap/*" ]
}
...
If the problem still remains, please, create an issue in the github project: