Skip to content

Commit 6565276

Browse files
wayneparrottMinggang Wang
authored andcommitted
Improve client and service typing support.
Key changes * Converted the following main typescript classes created by Node to interfaces: Client, Entity, GuardCondition, Publisher, Rate, Subscription * Refactored Client and Service to generic interfaces * Refactored rostsd_gen/index.js to produce ServiceConstructors, Service and ServiceType types. All maps are generated with keys in alphabetical order. Detects and ignores invalid actions and services. * Updated service and client tests in test/type/main.ts
1 parent 08e81ee commit 6565276

File tree

13 files changed

+340
-293
lines changed

13 files changed

+340
-293
lines changed

rostsd_gen/index.js

Lines changed: 212 additions & 190 deletions
Large diffs are not rendered by default.

test/types/main.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ const subscription = node.createSubscription(
128128
subscription.topic;
129129

130130
// ---- Service ----
131-
// $ExpectType Service
131+
// $ExpectType AddTwoIntsConstructor
132132
const service = node.createService(
133-
TYPE_CLASS,
134-
'abc',
133+
'example_interfaces/srv/AddTwoInts',
134+
'add_two_ints',
135135
{},
136-
(request: rclnodejs.Message, response: rclnodejs.ServiceResponse) => {}
136+
(request, response) => {}
137137
);
138138

139139
// $ExpectType string
@@ -143,8 +143,8 @@ service.serviceName;
143143
service.options;
144144

145145
// ---- Client ----
146-
// $ExpectType Client
147-
const client = node.createClient(TYPE_CLASS, 'abc');
146+
// $ExpectType Client<"example_interfaces/srv/AddTwoInts">
147+
const client = node.createClient('example_interfaces/srv/AddTwoInts', 'add_two_ints');
148148

149149
// $ExpectType string
150150
client.serviceName;

test/types/test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference path='../../types/index.d.ts' />
2+
import * as rclnodejs from 'rclnodejs';
3+
4+
5+
// ---- Uint8Array ----
6+
const u8arr = rclnodejs.require('example_interfaces.msg.UInt8MultiArray') as rclnodejs.example_interfaces.msg.UInt8MultiArray;
7+
// $ExpectType number[] | Uint8Array
8+
u8arr.data;
9+
10+
// ---- Uint8Array ----
11+
const u8arrx = rclnodejs.require('std_msgs.msg.UInt8MultiArray') as rclnodejs.std_msgs.msg.UInt8MultiArray;
12+
// $ExpectType number[] | Uint8Array
13+
u8arrx.data;

types/client.d.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ declare module 'rclnodejs' {
22
/**
33
* A ROS service client.
44
*/
5-
class Client extends Entity {
5+
interface Client<T extends TypeClass<ServiceTypeClassName>> extends Entity {
66
/**
77
* Make a service request and wait for to be notified asynchronously through a callback.
88
*
99
* @param request - Request to be submitted.
1010
* @param callback - Callback for receiving the server response.
1111
*/
12-
sendRequest(request: Message, callback: Client.ResponseCallback): void;
12+
sendRequest(
13+
request: ServiceRequestMessage<T>,
14+
callback: Client.ResponseCallback<T>): void;
1315

1416
/**
1517
* Checks if the service is ready.
@@ -40,6 +42,7 @@ declare module 'rclnodejs' {
4042
}
4143

4244
namespace Client {
45+
4346
/**
4447
* A callback for receiving a response from the service
4548
*
@@ -51,6 +54,7 @@ declare module 'rclnodejs' {
5154
* See {@link Client}
5255
* See {@link Service}
5356
*/
54-
export type ResponseCallback = (response: Message) => void;
57+
export type ResponseCallback<T extends TypeClass<ServiceTypeClassName>> =
58+
(response: ServiceResponseMessage<T>) => void;
5559
}
5660
}

types/entity.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ declare module 'rclnodejs' {
22
/**
33
* A common object in RCL.
44
*/
5-
class Entity {
5+
interface Entity {
66
options: object;
77
readonly qos: QoS;
88
readonly typedArrayEnabled: boolean;

types/guard_condition.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ declare module 'rclnodejs' {
33
* A ROS guard condition containing a callback executed when the
44
* guard condition is triggered.
55
*/
6-
class GuardCondition extends Entity {
6+
interface GuardCondition extends Entity {
77
/**
88
* Triggers the guard condition.
99
*/

types/index.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { MessageTypeClassName } from "rclnodejs";
2-
31
// eslint-disable-next-line spaced-comment
42
/// <reference path="base.d.ts" />
53

types/node.d.ts

Lines changed: 10 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
11
/* eslint-disable camelcase */
2-
3-
import { Clock, TypeClassName, MessageTypeClassName } from 'rclnodejs';
4-
import { Logging } from 'rclnodejs';
5-
import { Parameter, ParameterDescriptor, ParameterType } from 'rclnodejs';
6-
import { QoS } from 'rclnodejs';
7-
import { rcl_interfaces } from 'rclnodejs';
8-
92
declare module 'rclnodejs' {
103
/**
114
* Identifies type of ROS message such as msg or srv.
@@ -60,71 +53,6 @@ declare module 'rclnodejs' {
6053
*/
6154
const DEFAULT_OPTIONS: Options;
6255

63-
/**
64-
* A service response to a client request.
65-
*
66-
* @remarks
67-
* You can use {@link response.template | response.template} to get an empty result message.
68-
*/
69-
class ServiceResponse {
70-
/**
71-
* Get an empty response message object.
72-
* The template will be a message of type: <pkg>.srv.<serviceTypeClass>_Response.
73-
* e.g., example_interface/srv/AddTwoInts_Response
74-
*/
75-
readonly template: Message;
76-
77-
/**
78-
* The service that this response object is attaching to.
79-
*/
80-
readonly service: Service;
81-
82-
/**
83-
* Send this response to client (the service caller)
84-
*
85-
* @param response - Response message.
86-
*
87-
* @remarks
88-
* see {@link Response.template}
89-
*/
90-
send(response: Message): void;
91-
}
92-
93-
/**
94-
* A callback for receiving published messages.
95-
*
96-
* @param message - The published message.
97-
*
98-
* @remarks
99-
* See {@link Node#createSubscription | Node.createSubscription}
100-
* See {@link Node#createPublisher | Node.createPublisher}
101-
* See {@link Publisher}
102-
* See {@link Subscription}
103-
*/
104-
type SubscriptionCallback<T extends TypeClass<MessageTypeClassName>> =
105-
// * @param message - The published message
106-
(message: MessageType<T> | Buffer) => void;
107-
108-
/**
109-
* Callback for receiving service requests from a client.
110-
*
111-
* @param request - The request sent to the service
112-
* @param response - The response to the client.
113-
*
114-
* @remarks
115-
* Use {@link Response.send | response.send()} to send response object to client
116-
*
117-
* See {@link Node.createService | Node.createService}
118-
* See {@link Client.sendRequest | Client.sendRequest}
119-
* See {@link Client}
120-
* See {@link Service}
121-
* See {@link Response.send | Response.send}
122-
*/
123-
type ServiceRequestCallback = (
124-
request: Message,
125-
response: ServiceResponse
126-
) => void;
127-
12856
/**
12957
* Callback for receiving periodic interrupts from a Timer.
13058
*
@@ -283,7 +211,7 @@ declare module 'rclnodejs' {
283211
topic: string,
284212
options: Options,
285213
callback: SubscriptionCallback<T>
286-
): Subscription;
214+
): Subscription
287215

288216
/**
289217
* Create a Client for making server requests.
@@ -293,11 +221,11 @@ declare module 'rclnodejs' {
293221
* @param options - The options argument used to parameterize the client.
294222
* @returns New instance of Client.
295223
*/
296-
createClient(
297-
typeClass: TypeClass,
224+
createClient<T extends TypeClass<ServiceTypeClassName>>(
225+
typeClass: T,
298226
serviceName: string,
299227
options?: Options
300-
): Client;
228+
): Client<T>;
301229

302230
/**
303231
* Create a Service.
@@ -308,12 +236,12 @@ declare module 'rclnodejs' {
308236
* @param callback - Notified for receiving incoming requests.
309237
* @returns An instance of Service.
310238
*/
311-
createService(
312-
typeClass: TypeClass,
239+
createService<T extends TypeClass<ServiceTypeClassName>>(
240+
typeClass: T,
313241
serviceName: string,
314242
options: Options,
315-
callback: ServiceRequestCallback
316-
): Service;
243+
callback: ServiceRequestHandler<T>
244+
): ServiceType<T>;
317245

318246
/**
319247
* Create a guard condition.
@@ -335,7 +263,7 @@ declare module 'rclnodejs' {
335263
*
336264
* @param publisher - Publisher to be destroyed.
337265
*/
338-
destroyPublisher<T extends MessageTypeClassName>(publisher: Publisher<T>): void;
266+
destroyPublisher<T extends TypeClass<MessageTypeClassName>>(publisher: Publisher<T>): void;
339267

340268
/**
341269
* Destroy a Subscription.
@@ -349,7 +277,7 @@ declare module 'rclnodejs' {
349277
*
350278
* @param client - Client to be destroyed.
351279
*/
352-
destroyClient(client: Client): void;
280+
destroyClient<T extends TypeClass<ServiceTypeClassName>>(client: Client<T>): void;
353281

354282
/**
355283
* Destroy a Service.

types/publisher.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { MessageTypeClassName } from 'rclnodejs';
2-
31
declare module 'rclnodejs' {
42
/**
53
* A ROS Publisher that publishes messages on a topic.
64
*/
7-
class Publisher<T extends TypeClass<MessageTypeClassName>> extends Entity {
5+
interface Publisher<T extends TypeClass<MessageTypeClassName>> extends Entity {
86
/**
97
* Topic on which messages are published.
108
*/

types/rate.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ declare module 'rclnodejs' {
2828
* }
2929
* }
3030
*/
31-
export class Rate {
31+
export interface Rate {
3232
/**
3333
* Get the frequency in hertz (hz) of this timer.
3434
*

0 commit comments

Comments
 (0)