or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-tool.mdindex.mdproto-loading.mdtype-definitions.md
tile.json

cli-tool.mddocs/

CLI Type Generation Tool

Command-line utility for generating TypeScript type definitions from .proto files, enabling type-safe gRPC development in TypeScript projects.

Capabilities

proto-loader-gen-types Command

The CLI tool generates TypeScript interface and type definitions from Protocol Buffer files.

proto-loader-gen-types [options] filenames...

Installation and Usage:

# Install package
npm install @grpc/proto-loader

# Generate types
npx proto-loader-gen-types --longs=String --enums=String --defaults --oneofs --grpcLib=@grpc/grpc-js --outDir=proto/ proto/*.proto

# Or use directly from node_modules
$(npm bin)/proto-loader-gen-types --outDir=types/ service.proto

Command Options

OptionTypeDefaultDescription
--helpboolean-Show help information
--versionboolean-Show version number
--keepCasebooleanfalsePreserve the case of field names
--longsstring"Long"The type for 64-bit integer values. Can be "String", "Number"
--enumsstring"number"The type for enum fields. Can be "String"
--bytesstring"Buffer"The type for bytes fields. Can be "String", "Array"
--defaultsbooleanfalseOutput default values for omitted fields
--arraysbooleanfalseOutput default values for omitted repeated fields even if --defaults is not set
--objectsbooleanfalseOutput default values for omitted message fields even if --defaults is not set
--oneofsbooleanfalseOutput virtual oneof fields set to the present field's name
--jsonbooleanfalseRepresent Infinity and NaN as strings in float fields. Also decode google.protobuf.Any automatically
--includeCommentsbooleanfalseGenerate doc comments from comments in the original files
-I, --includeDirsarray-Directories to search for included files
-O, --outDirstringrequiredDirectory to output generated files
--grpcLibstring-The gRPC implementation library (affects generated types)
--inputTemplatestring"%s"Template for mapping input or "permissive" type names
--outputTemplatestring"%s__Output"Template for mapping output or "restricted" type names
--inputBrandedbooleanfalseOutput property for branded type for "permissive" types
--outputBrandedbooleanfalseOutput property for branded type for "restricted" types
--targetFileExtensionstring".ts"File extension for generated files
--importFileExtensionstring""File extension for import specifiers in generated code

Common Usage Examples

Basic Type Generation

# Generate basic TypeScript types
proto-loader-gen-types --outDir=./types proto/service.proto

# Multiple proto files
proto-loader-gen-types --outDir=./types proto/*.proto

gRPC-Compatible Types

# Generate types compatible with @grpc/grpc-js
proto-loader-gen-types \
  --longs=String \
  --enums=String \
  --defaults \
  --oneofs \
  --grpcLib=@grpc/grpc-js \
  --outDir=./proto \
  proto/*.proto

Advanced Configuration

# Generate with custom templates and comments
proto-loader-gen-types \
  --longs=String \
  --enums=String \
  --defaults \
  --oneofs \
  --includeComments \
  --inputTemplate="I%s" \
  --outputTemplate="O%s" \
  --grpcLib=@grpc/grpc-js \
  -I ./proto \
  -I ./external-proto \
  --outDir=./generated \
  proto/service.proto

Generated Type Structure

The CLI tool generates several types of TypeScript definitions:

Service Types

// Generated service interface
export interface MyServiceHandlers extends grpc.UntypedServiceImplementation {
  myMethod: grpc.handleUnaryCall<MyRequest, MyResponse>;
  myStreamMethod: grpc.handleServerStreamingCall<MyRequest, MyResponse>;
}

// Generated service definition
export const MyServiceService: grpc.ServiceDefinition<MyServiceHandlers>;

Message Types

// Input type (permissive, for creating messages)
export interface MyMessage {
  field1?: string;
  field2?: number;
  optionalField?: string;
}

// Output type (with defaults applied, for receiving messages)
export interface MyMessage__Output {
  field1: string;
  field2: number;
  optionalField: string;
}

Enum Types

// Enum as const object
export const MyEnum = {
  VALUE1: 'VALUE1',
  VALUE2: 'VALUE2',
} as const;

// Enum type
export type MyEnum = 'VALUE1' | 'VALUE2';
export type MyEnum__Output = typeof MyEnum[keyof typeof MyEnum];

Package Root Type

// Complete package type combining all definitions
export interface ProtoGrpcType {
  mypackage: {
    MyService: SubtypeConstructor<typeof grpc.Client, MyServiceHandlers>;
    MyMessage: MessageTypeDefinition;
    MyEnum: EnumTypeDefinition;
  };
}

Integration with Code

Server Implementation

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import type { ProtoGrpcType } from './proto/service';
import type { MyServiceHandlers } from './proto/mypackage/MyService';

const packageDefinition = protoLoader.loadSync('./proto/service.proto');
const proto = (grpc.loadPackageDefinition(
  packageDefinition
) as unknown) as ProtoGrpcType;

const server = new grpc.Server();

const serviceImplementation: MyServiceHandlers = {
  myMethod: (call, callback) => {
    // call.request is strongly typed
    const response = { message: `Hello ${call.request.name}` };
    callback(null, response);
  },
};

server.addService(proto.mypackage.MyService.service, serviceImplementation);

Client Usage

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import type { ProtoGrpcType } from './proto/service';
import type { MyServiceClient } from './proto/mypackage/MyService';

const packageDefinition = protoLoader.loadSync('./proto/service.proto');
const proto = (grpc.loadPackageDefinition(
  packageDefinition
) as unknown) as ProtoGrpcType;

const client = new proto.mypackage.MyService(
  'localhost:50051',
  grpc.credentials.createInsecure()
) as MyServiceClient;

// Type-safe method calls
client.myMethod({ name: 'World' }, (error, response) => {
  if (!error) {
    // response is strongly typed
    console.log(response.message);
  }
});

Custom Templates

The CLI tool supports custom naming templates for generated types:

Input/Output Templates

# Use I/O prefixes
proto-loader-gen-types \
  --inputTemplate="I%s" \
  --outputTemplate="O%s" \
  --outDir=./types \
  service.proto

This generates:

// Input types (permissive)
export interface IMyMessage {
  field?: string;
}

// Output types (with defaults)
export interface OMyMessage {
  field: string;
}

Branded Types

# Generate branded types for additional type safety
proto-loader-gen-types \
  --inputBranded \
  --outputBranded \
  --outDir=./types \
  service.proto

Error Handling

The CLI tool provides detailed error messages for common issues:

  • Proto file not found: Clear file path errors
  • Parse errors: Line-by-line syntax error reporting
  • Import resolution: Missing import file reporting
  • Output directory: Permission and path validation

Example Error Output:

Error: Proto file not found: ./proto/service.proto
  at loadProtos (/path/to/proto-loader-gen-types.js:123:45)
  
Error: Parse error in service.proto:15:3
  syntax error: expected ';' after field definition

Build Integration

Package.json Scripts

{
  "scripts": {
    "proto:gen": "proto-loader-gen-types --longs=String --enums=String --defaults --oneofs --grpcLib=@grpc/grpc-js --outDir=src/proto proto/*.proto",
    "proto:watch": "chokidar 'proto/*.proto' -c 'npm run proto:gen'",
    "prebuild": "npm run proto:gen"
  }
}

Build Tools Integration

// webpack.config.js - Generate types before build
const { execSync } = require('child_process');

module.exports = {
  // ... other config
  plugins: [
    {
      apply: (compiler) => {
        compiler.hooks.beforeCompile.tap('ProtoGen', () => {
          execSync('npm run proto:gen', { stdio: 'inherit' });
        });
      }
    }
  ]
};