-
Notifications
You must be signed in to change notification settings - Fork 143
Open
Description
Calling .create()
on a MessageType
instance allows partial oneof fields at runtime, but at compile-time they are required to be non-partial. TS Playground
// pulled from https://github.com/timostamm/protobuf-ts/blob/master/packages/runtime/src/message-type-contract.ts
export type PartialMessage<T extends object> = {
[K in keyof T]?: PartialField<T[K]>
}; type PartialField<T> =
T extends (Date | Uint8Array | bigint | boolean | string | number) ? T
: T extends Array<infer U> ? Array<PartialField<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<PartialField<U>>
: T extends { oneofKind: string } ? T
: T extends { oneofKind: undefined } ? T
: T extends object ? PartialMessage<T>
: T ;
// example
interface Bar {
arr: number[];
other?: number;
}
interface Foo {
args: {
oneofKind: "bar";
bar: Bar;
} | {
oneofKind: undefined;
}
}
function create(i: PartialMessage<Foo>) {}
create({
args: {
oneofKind: 'bar',
bar: { // ts-2741: Property 'arr' is missing in type '{ other: number; }' but required in type 'Bar'.
other: 1,
}
}
})
I don't think there's actually a way to get this working given the existing types. This is another instance where the updated oneof representation would make this trivial: : T extends { kind: string; value: infer U } ? { kind: T['kind']; value: PartialField<U> }
.
Metadata
Metadata
Assignees
Labels
No labels