Skip to content

Commit

Permalink
Fix assignability of wrong message type in create
Browse files Browse the repository at this point in the history
  • Loading branch information
timostamm committed Sep 18, 2024
1 parent 351e202 commit 50e8324
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 5 deletions.
26 changes: 26 additions & 0 deletions packages/protobuf-test/extra/ts-types-proto2.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2021-2024 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto2";
package spec;

message TsTypeA {
optional string str = 1;
optional TsTypeA child = 2;
}

message TsTypeB {
optional string str = 1;
optional TsTypeB child = 2;
}
7 changes: 7 additions & 0 deletions packages/protobuf-test/src/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import * as proto3_ts from "./gen/ts/extra/proto3_pb.js";
import * as proto2_ts from "./gen/ts/extra/proto2_pb.js";
import * as edition2023_ts from "./gen/ts/extra/edition2023_pb.js";
import * as test_messages_proto3_editions_ts from "./gen/ts/editions/golden/test_messages_proto3_editions_pb.js";
import * as ts_types from "./gen/ts/extra/ts-types-proto2_pb.js";
import { fillProto3Message, fillProto3MessageNames } from "./helpers-proto3.js";
import {
fillEdition2023Message,
Expand Down Expand Up @@ -549,6 +550,12 @@ describe("create()", () => {
const notAUser = create(proto3_ts.Proto3MessageSchema, user);
expect(notAUser).toBeDefined();
});
test("rejects foreign typed message with assignable properties as a type error", () => {
const a = create(ts_types.TsTypeASchema);
// @ts-expect-error TS2345: Argument of type TsTypeA is not assignable to parameter of type MessageInit<TsTypeB> | undefined
const b = create(ts_types.TsTypeBSchema, a);
expect(b).toBeDefined();
});
test("rejects extra properties in the object literal as a type error", () => {
const msg = create(proto3_ts.Proto3MessageSchema, {
// @ts-expect-error TS2353
Expand Down
68 changes: 68 additions & 0 deletions packages/protobuf-test/src/gen/js/extra/ts-types-proto2_pb.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions packages/protobuf-test/src/gen/js/extra/ts-types-proto2_pb.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions packages/protobuf-test/src/gen/ts/extra/ts-types-proto2_pb.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions packages/protobuf/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type MessageJsonType<Desc extends DescMessage> =
*/
export type MessageInitShape<Desc extends DescMessage> =
Desc extends GenMessage<infer RuntimeShape>
? RuntimeShape | MessageInit<RuntimeShape>
? MessageInit<RuntimeShape>
: Record<string, unknown>;

/**
Expand Down Expand Up @@ -93,10 +93,11 @@ export type UnknownField = {
* The init type for a message, which makes all fields optional.
* The init type is accepted by the function create().
*/
type MessageInit<T extends Message> = {
[P in keyof T as P extends "$typeName" | "$unknown" ? never : P]?: FieldInit<
T[P]
>;
// prettier-ignore
type MessageInit<T extends Message> = T | {
[P in keyof T as P extends "$unknown" ? never : P]?: P extends "$typeName"
? never
: FieldInit<T[P]>;
};

// prettier-ignore
Expand Down

0 comments on commit 50e8324

Please sign in to comment.