Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper types for HandlerFunctions #370

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
### Added
- Added missing properties for `log` in `cds.env`
- Added overload for `service.read` to be called with a `ref`
- Added `HandlerFunction.parameters.req` and `HandlerFunction.returns` to type handler functions that are not declared as lambdas more conveniently

### Removed
- [breaking] Removed type `TypedRequest<T>` and replaced it with just `Request<T>`
Expand Down
25 changes: 25 additions & 0 deletions apis/services.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,37 @@ type OneOrMany<T> = T | T[]
// parameters and return type, as their names are not accessible from
// function signatures to the type system.
// This meta information is required in .on action handlers.
/**
* @beta helper
*/
type CdsFunction = {
(...args: any[]): any,
__parameters: object,
__returns: any,
}

/**
* Types herein can be used to type handler functions that are not declared in line:
* @example
* ```ts
* import { myAction } from '#cds-models/myService'
*
* function onMyFunction (req: HandlerFunction<typeof myAction>['parameters']['req']): HandlerFunction<typeof myAction>['returns'] {
* ...
* }
*
* srv.on(myAction, onMyFunction)
* ```
*/
export type HandlerFunction<F extends CdsFunction> = {
parameters: {
/** @beta helper */
req: Request<F['__parameters']>,
},
/** @beta helper */
returns: F['__returns'],
}

// https://cap.cloud.sap/docs/node.js/core-services#srv-on-before-after
declare namespace CRUDEventHandler {
type Before<P, R = P | void | Error> = (req: Request<P>) => Promise<R> | R
Expand Down
13 changes: 11 additions & 2 deletions test/typescript/apis/project/cds-services.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cds, { Service, Request } from '@sap/cds'
import { Bars, Bar, Foo, Foos, action } from './dummy'
import cds, { Service, Request, HandlerFunction } from '@sap/cds'
import { Bars, Bar, Foo, Foos, action, as, testType } from './dummy'
const model = cds.reflect({})
const { Book: Books } = model.entities
import express from 'express'
Expand Down Expand Up @@ -439,3 +439,12 @@ srv.entities('namespace');

// @ts-expect-error
srv.entities('namespace')('and again')

type ActionType = HandlerFunction<typeof action>
srv.on(action, externalActionHandler)
function externalActionHandler(req: ActionType['parameters']['req']): ActionType['returns'] {
testType<Foo>(req.data.foo)
return 42
}

testType<number>(externalActionHandler(as<HandlerFunction<typeof action>['parameters']['req']>()))
Loading