From 52aeb62875b9aee42e34ca41b62d6c4d601183cb Mon Sep 17 00:00:00 2001 From: Stephen Niedzielski Date: Thu, 21 Apr 2022 13:55:33 -0600 Subject: [PATCH] feat: include service and definition types with implementations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When exporting a service or service definition, also export it as a type. Previously, you would have to import the value then `typeof` off of it which is cumbersome. Automate this as it has no runtime overhead and seems more intuitive. Before: ```ts export const TestDefinition = { name: 'Test', fullName: 'simple.Test', methods: { … }, } as const; ``` After: ```ts export type TestDefinition = typeof TestDefinition; export const TestDefinition = { name: 'Test', fullName: 'simple.Test', methods: { … }, } as const; ``` --- CHANGELOG.md | 29 +++++++++++++++++++ integration/generic-metadata/hero.ts | 1 + .../simple.ts | 1 + .../generic-service-definitions/simple.ts | 1 + integration/grpc-js/simple.ts | 1 + integration/use-date-true/use-date-true.ts | 1 + src/generate-generic-service-definition.ts | 8 ++++- src/generate-grpc-js.ts | 8 ++++- 8 files changed, 48 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 061a29b7f..24db5dd52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ +## [next](https://github.com/stephenh/ts-proto/compare/v1.110.4...main) (????-??-??) + +### Features + +* When outputing service and service definition implementations, include types. Eg, before: + + ```ts + export const TestDefinition = { + name: 'Test', + fullName: 'simple.Test', + methods: { + … + }, + } as const; + ``` + + Now: + + ```ts + export type TestDefinition = typeof TestDefinition; + export const TestDefinition = { + name: 'Test', + fullName: 'simple.Test', + methods: { + … + }, + } as const; + ``` + ## [1.110.4](https://github.com/stephenh/ts-proto/compare/v1.110.3...v1.110.4) (2022-04-08) diff --git a/integration/generic-metadata/hero.ts b/integration/generic-metadata/hero.ts index 3bca7c110..1f43611ed 100644 --- a/integration/generic-metadata/hero.ts +++ b/integration/generic-metadata/hero.ts @@ -272,6 +272,7 @@ export class HeroServiceClientImpl implements HeroService { } } +export type HeroServiceDefinition = typeof HeroServiceDefinition; export const HeroServiceDefinition = { name: 'HeroService', fullName: 'hero.HeroService', diff --git a/integration/generic-service-definitions-and-services/simple.ts b/integration/generic-service-definitions-and-services/simple.ts index 94178885a..0890c6919 100644 --- a/integration/generic-service-definitions-and-services/simple.ts +++ b/integration/generic-service-definitions-and-services/simple.ts @@ -58,6 +58,7 @@ export const TestMessage = { }; /** @deprecated */ +export type TestDefinition = typeof TestDefinition; export const TestDefinition = { name: 'Test', fullName: 'simple.Test', diff --git a/integration/generic-service-definitions/simple.ts b/integration/generic-service-definitions/simple.ts index 94178885a..0890c6919 100644 --- a/integration/generic-service-definitions/simple.ts +++ b/integration/generic-service-definitions/simple.ts @@ -58,6 +58,7 @@ export const TestMessage = { }; /** @deprecated */ +export type TestDefinition = typeof TestDefinition; export const TestDefinition = { name: 'Test', fullName: 'simple.Test', diff --git a/integration/grpc-js/simple.ts b/integration/grpc-js/simple.ts index 0ccca1237..6111e5301 100644 --- a/integration/grpc-js/simple.ts +++ b/integration/grpc-js/simple.ts @@ -94,6 +94,7 @@ export const TestMessage = { * * @deprecated */ +export type TestService = typeof TestService; export const TestService = { /** * Unary diff --git a/integration/use-date-true/use-date-true.ts b/integration/use-date-true/use-date-true.ts index e966574c3..4ddfb09d2 100644 --- a/integration/use-date-true/use-date-true.ts +++ b/integration/use-date-true/use-date-true.ts @@ -206,6 +206,7 @@ export class ClockClientImpl implements Clock { } } +export type ClockDefinition = typeof ClockDefinition; export const ClockDefinition = { name: 'Clock', fullName: 'Clock', diff --git a/src/generate-generic-service-definition.ts b/src/generate-generic-service-definition.ts index 53d25cfff..add3e6696 100644 --- a/src/generate-generic-service-definition.ts +++ b/src/generate-generic-service-definition.ts @@ -25,9 +25,15 @@ export function generateGenericServiceDefinition( maybeAddComment(sourceInfo, chunks, serviceDesc.options?.deprecated); + // Service definition type + const name = def(`${serviceDesc.name}Definition`); + chunks.push(code` + export type ${name} = typeof ${name}; + `); + // Service definition chunks.push(code` - export const ${def(`${serviceDesc.name}Definition`)} = { + export const ${name} = { `); serviceDesc.options?.uninterpretedOption; diff --git a/src/generate-grpc-js.ts b/src/generate-grpc-js.ts index fefc49e53..408d7eea0 100644 --- a/src/generate-grpc-js.ts +++ b/src/generate-grpc-js.ts @@ -57,9 +57,15 @@ function generateServiceDefinition( maybeAddComment(sourceInfo, chunks, serviceDesc.options?.deprecated); + // Service definition type + const name = def(`${serviceDesc.name}Service`); + chunks.push(code` + export type ${name} = typeof ${name}; + `); + // Service definition chunks.push(code` - export const ${def(`${serviceDesc.name}Service`)} = { + export const ${name} = { `); for (const [index, methodDesc] of serviceDesc.method.entries()) {