Skip to content

Valid types

Valid types are an advanced feature enabled with the plugin option valid_types.

When enabled, @bufbuild/protoc-gen-es generates an extra type for each message. The extra type adjusts optionality based on Protobuf features and validation rules so the TypeScript type can reflect runtime guarantees more closely.

[!NOTE]

Valid types are experimental. Today they primarily affect message field optionality.

With legacy_required, proto2 required message fields and Edition LEGACY_REQUIRED message fields become non-optional in the generated Valid type.

syntax = "proto2";
message Example {
required User user = 2;
}
message User {
optional string first_name = 1;
}
export type ExampleValid = Message<"Example"> & {
user: UserValid;
};

With protovalidate_required, message fields marked with Protovalidate’s required rule become non-optional in the generated Valid type.

syntax = "proto3";
import "buf/validate/validate.proto";
message Example {
User user = 2 [(buf.validate.field).required = true];
}

This is useful when you want the type system to reflect runtime validation rules more closely.

You can combine both behaviors:

valid_types=legacy_required+protovalidate_required

Protobuf-ES also provides:

  • MessageValidType: Extract the Valid type from a message descriptor.

When writing plugins, GeneratedFile.importValid() imports a generated Valid type.

For a concrete integration example, see the Protovalidate-ES example.