Description
When using ts-proto via buf with useNullAsOptional=true
, fields declared as optional float
in your .proto
schema generate TypeScript interfaces allowing null
:
message Weight {
string id = 1;
string unit = 2;
// value is optional
optional float value = 3;
string createdAt = 5;
string updatedAt = 6;
}
export interface Weight {
id: string;
unit: string;
/** value is optional */
value?: number | null | undefined;
createdAt: string;
updatedAt: string;
}
However, fromPartial
's signature only permits number | undefined
for value
, crashing when you pass null
.
Reproduction Steps
-
Create a
buf.gen.yaml
with ts-proto plugin anduseNullAsOptional=true
:version: v1 plugins: - name: ts-proto path: ./node_modules/.bin/protoc-gen-ts_proto out: src/generated/test opt: - esModuleInterop=true - outputServices=grpc-js - env=node - strict=true - useNullAsOptional=true - outputClientImpl=false
-
Define the message in your
.proto
file (as above). -
Run
buf generate
to emit.ts
files. -
Attempt to call:
import { Weight } from "./generated/test"; const partial = { id: "abc", unit: "kg", value: null }; // A Prisma ORM result const w = Weight.fromPartial(partial); // Type error: Argument of type '{ value: null; }' is not assignable...
Expected Behavior
Since the generated interface allows value
to be null
, fromPartial
should also accept null
:
declare function fromPartial<I extends DeepPartial<Weight>>(object: I): Weight;
should allow object.value
to be null
.
Actual Behavior
fromPartial
only accepts number | undefined
:
value?: (number | undefined);
Passing null
yields a TypeScript compile error.
Workaround
Editing the generated helper types:
// before
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
// after
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined | null;
fixes the error, but is obviously not ideal.
Questions
- Is this a bug in ts-proto’s
fromPartial
generator, givenuseNullAsOptional=true
? - If not, is there a recommended configuration or flag to ensure
fromPartial
acceptsnull
for optional scalar fields? - Would a PR to include
null
in the built-in type union be acceptable?
Thank you for your help! 😃