Using TypeScript
While CAP itself is written in JavaScript, it's possible to use TypeScript within your project as outlined here.
Enable TypeScript Support
Follow these steps to add TypeScript support:
Install typescript packages globally:
shnpm i -g typescript ts-node
Add a basic tsconfig.json file to your project:
shcds add typescript
You can modify this configuration file to match your project setup. See the official TypeScript documentation for more details. Note that adding the
typescript
facet,cds-typer
is also automatically added to your project.
Developing with cds-tsx
since @sap/cds-dk 8.2.0 beta
Use the cds-tsx
CLI command instead of cds
to avoid having to precompile TypeScript files to JavaScript each time and speed up development:
cds-tsx watch
cds-tsx serve world.cds
When using the binary cds-tsx
, the tsx engine is used to start the project instead of the default node engine. You can install it globally with:
npm i -g tsx
Not for production
cds-tsx
/ tsx
should be used for development only. For productive usage always precompile TypeScript code to JavaScript for best performance and use cds-serve
as usual.
Writing TypeScript Files
Once you've setup everything correctly, you can start writing TypeScript files instead of JavaScript files. This applies for service handlers, as well as a custom server.ts file or database init.ts seeding files.
Samples
You can also download the Hello World! TypeScript sample or try out the Full Stack TypeScript App.
Developing with cds-ts
Much like cds-tsx
, you can also use the cds-ts
CLI command:
cds-ts watch
cds-ts serve world.cds
It uses the ts-node engine under the hood.
cds-tsx or cds-ts?
In general, cds-tsx
seems to be the better choice as tsx
is much faster than ts-node
because it does not perform type checks. See a closer comparison between the two of them.
Testing with ts-jest
Run your Jest tests with preset ts-jest
without precompiling TypeScript files.
Install
ts-jest
locally:shnpm install -D ts-jest
Tell Jest to use the preset
ts-jest
, for example, in your jest.config.js:jsmodule.exports = { preset: "ts-jest", globalSetup: "./test/setup.ts" };
Set
CDS_TYPESCRIPT
environment variable:This is necessary, because it isn't possible to programmatically detect that the preset
ts-jest
is used and we've to know whether we need to look for .ts or .js files.File ./test/setup.ts, content:
jsmodule.exports = async () => { process.env.CDS_TYPESCRIPT = "true"; };
Run your tests as usual:
shjest
Building TypeScript Projects
A dedicated build task for cds build
is provided as part of the cds-typer
package. See Integrate Into Your Multitarget Application for more information on how to customize this task.
TypeScript APIs in @sap/cds
The package @sap/cds
is shipped with TypeScript declarations. These declarations are used automatically when you write TypeScript files, but also enable IntelliSense and type checking for standard JavaScript development in Visual Studio Code.
Use them like this:
import { Request } from '@sap/cds'
function myHandler(req: Request) { }
Types are available even in JavaScript through JSDoc comments:
/**
* @param { import('@sap/cds').Request } req
*/
function myHandler(req) { }
Type Imports
Import types through the cds
facade class only:
Good:
import { ... } from '@sap/cds'
Bad:
Never code against paths inside @sap/cds/apis/
:
import { ... } from '@sap/cds/apis/events'
Community
Help us improve the types
We invite you to contribute and help us complete the typings as appropriate. Find the sources on GitHub and open a pull request or an issue.
Still, as @sap/cds
is a JavaScript library, typings aren't always up to date. You should expect a delay for typings related to the latest release, even gaps, and errors.
Generating Model Types Automatically
The cds-typer
package offers a way to derive TypeScript definitions from a CDS model to give you enhanced code completion and a certain degree of type safety when implementing services.
class CatalogService extends cds.ApplicationService { init() {
const { Book } = require('#cds-models/sap/capire/bookshop')
this.before('CREATE', Book, req => {
req.data.… // known to be a Book. Code completion suggests:
// ID (number)
// title (string)
// author (Author)
// createdAt (Date)
// …
})
}}
You can find extensive documentation in a dedicated chapter, together with a quickstart guide to get everything up and running.