ts-proto 1.91.0 → 1.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.92.0](https://github.com/stephenh/ts-proto/compare/v1.91.0...v1.92.0) (2021-11-28)
2
+
3
+
4
+ ### Features
5
+
6
+ * Use exact types for fromPartial ([#412](https://github.com/stephenh/ts-proto/issues/412)) ([808f8a7](https://github.com/stephenh/ts-proto/commit/808f8a7a77d56f65dd4a4643dd66158f106ab755)), closes [#156](https://github.com/stephenh/ts-proto/issues/156)
7
+
1
8
  # [1.91.0](https://github.com/stephenh/ts-proto/compare/v1.90.1...v1.91.0) (2021-11-27)
2
9
 
3
10
 
@@ -13,7 +13,7 @@ function generateTypeRegistry(ctx) {
13
13
  chunks.push(ts_poet_1.code `
14
14
  export const messageTypeRegistry = new Map<string, MessageType>();
15
15
  `);
16
- chunks.push(ts_poet_1.code `${ctx.utils.DeepPartial.ifUsed}`);
16
+ chunks.push(ts_poet_1.code ` ${ctx.utils.Builtin.ifUsed} ${ctx.utils.DeepPartial.ifUsed}`);
17
17
  return ts_poet_1.joinCode(chunks, { on: '\n\n' });
18
18
  }
19
19
  exports.generateTypeRegistry = generateTypeRegistry;
package/build/main.js CHANGED
@@ -289,11 +289,20 @@ function makeDeepPartial(options, longs) {
289
289
  const maybeExport = options.exportCommonSymbols ? 'export' : '';
290
290
  // Allow passing longs as numbers or strings, nad we'll convert them
291
291
  const maybeLong = options.forceLong === options_1.LongOption.LONG ? ts_poet_1.code ` : T extends ${longs.Long} ? string | number | Long ` : '';
292
- const keys = options.outputTypeRegistry ? ts_poet_1.code `Exclude<keyof T, '$type'>` : ts_poet_1.code `keyof T`;
292
+ const Builtin = ts_poet_1.conditionalOutput('Builtin', ts_poet_1.code `type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;`);
293
+ // Based on https://github.com/sindresorhus/type-fest/pull/259
294
+ const maybeExcludeType = options.outputTypeRegistry ? `| '$type'` : '';
295
+ const Exact = ts_poet_1.conditionalOutput('Exact', ts_poet_1.code `
296
+ type KeysOfUnion<T> = T extends T ? keyof T : never;
297
+ ${maybeExport} type Exact<P, I extends P> = P extends ${Builtin}
298
+ ? P
299
+ : P &
300
+ { [K in keyof P]: Exact<P[K], I[K]> } & Record<Exclude<keyof I, KeysOfUnion<P> ${maybeExcludeType}>, never>;
301
+ `);
293
302
  // Based on the type from ts-essentials
303
+ const keys = options.outputTypeRegistry ? ts_poet_1.code `Exclude<keyof T, '$type'>` : ts_poet_1.code `keyof T`;
294
304
  const DeepPartial = ts_poet_1.conditionalOutput('DeepPartial', ts_poet_1.code `
295
- type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
296
- ${maybeExport} type DeepPartial<T> = T extends Builtin
305
+ ${maybeExport} type DeepPartial<T> = T extends ${Builtin}
297
306
  ? T
298
307
  ${maybeLong}
299
308
  : T extends Array<infer U>
@@ -304,7 +313,7 @@ function makeDeepPartial(options, longs) {
304
313
  ? { [K in ${keys}]?: DeepPartial<T[K]> }
305
314
  : Partial<T>;
306
315
  `);
307
- return { DeepPartial };
316
+ return { Builtin, DeepPartial, Exact };
308
317
  }
309
318
  function makeTimestampMethods(options, longs) {
310
319
  const Timestamp = ts_poet_1.imp('Timestamp@./google/protobuf/timestamp');
@@ -1045,8 +1054,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1045
1054
  const chunks = [];
1046
1055
  const Timestamp = ts_poet_1.imp('Timestamp@./google/protobuf/timestamp');
1047
1056
  // create the basic function declaration
1057
+ const paramName = messageDesc.field.length > 0 ? 'object' : '_';
1048
1058
  chunks.push(ts_poet_1.code `
1049
- fromPartial(${messageDesc.field.length > 0 ? 'object' : '_'}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
1059
+ fromPartial<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
1050
1060
  const message = { ...base${fullName} } as ${fullName};
1051
1061
  `);
1052
1062
  // add a check for each incoming field
@@ -1122,7 +1132,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1122
1132
  }
1123
1133
  else {
1124
1134
  chunks.push(ts_poet_1.code `
1125
- message.${fieldName} = (object.${fieldName} ?? []).map((e) => ${readSnippet('e')});
1135
+ message.${fieldName} = object.${fieldName}?.map((e) => ${readSnippet('e')}) || [];
1126
1136
  `);
1127
1137
  }
1128
1138
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.91.0",
3
+ "version": "1.92.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",