diff --git a/README.md b/README.md
index 284b082b5..f0c184a9f 100644
--- a/README.md
+++ b/README.md
@@ -106,7 +106,7 @@ Where bundle size is a factor, there are additional stripped-down versions of th
Usage
-----
-Because JavaScript is a dynamically typed language, protobuf.js introduces the concept of a **valid message** in order to provide the best possible [performance](#performance):
+Because JavaScript is a dynamically typed language, protobuf.js introduces the concept of a **valid message** in order to provide the best possible [performance](#performance) (and, as a side product, proper typings):
### Valid message
@@ -119,8 +119,8 @@ There are two possible types of valid messages and the encoder is able to work w
In a nutshell, the wire format writer understands the following types:
-| Field type | Expected JS type (create, encode) | Naive conversion (fromObject)
-|------------|-----------------------------------|------------------------------
+| Field type | Expected JS type (create, encode) | Conversion (fromObject)
+|------------|-----------------------------------|------------------------
| s-/u-/int32
s-/fixed32 | `number` (32 bit integer) | `value | 0` if signed
`value >>> 0` if unsigned
| s-/u-/int64
s-/fixed64 | `Long`-like (optimal)
`number` (53 bit integer) | `Long.fromValue(value)` with long.js
`parseInt(value, 10)` otherwise
| float
double | `number` | `Number(value)`
@@ -187,7 +187,7 @@ With that in mind and again for performance reasons, each message class provides
```
* **Message.fromObject**(object: `Object`): `Message`
- naively converts any non-valid **plain JavaScript object** to a **message instance**. See the table above for the exact conversion operations performed.
+ converts any non-valid **plain JavaScript object** to a **message instance** using the conversion steps outlined within the table above.
```js
var message = AwesomeMessage.fromObject({ awesomeField: 42 });
@@ -213,6 +213,8 @@ For reference, the following diagram aims to display the relationships between t
+> In other words: `verify` indicates that calling `create` or `encode` directly on the plain object will [result in a valid message respectively] succeed. `fromObject`, on the other hand, does conversion from a broader range of plain objects to create valid messages. ([ref](https://github.com/dcodeIO/protobuf.js/issues/748#issuecomment-291925749))
+
Examples
--------
@@ -247,7 +249,7 @@ protobuf.load("awesome.proto", function(err, root) {
throw Error(errMsg);
// Create a new message
- var message = AwesomeMessage.fromObject(payload); // or use .create if payload is already known to be valid
+ var message = AwesomeMessage.creeate(payload); // or use .fromObject if conversion is necessary
// Encode a message to an Uint8Array (browser) or Buffer (node)
var buffer = AwesomeMessage.encode(message).finish();
diff --git a/index.d.ts b/index.d.ts
index d03d3961a..d3982dcac 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -880,9 +880,9 @@ export abstract class NamespaceBase extends ReflectionObject {
/**
* Converts this namespace to a namespace descriptor.
- * @returns {NamespaceDescriptor} Namespace descriptor
+ * @returns {NamespaceBaseDescriptor} Namespace descriptor
*/
- public toJSON(): NamespaceDescriptor;
+ public toJSON(): NamespaceBaseDescriptor;
/**
* Adds nested objects to this namespace from nested object descriptors.
@@ -996,13 +996,20 @@ export abstract class NamespaceBase extends ReflectionObject {
public lookupService(path: (string|string[])): Service;
}
-type AnyNestedDescriptor = (EnumDescriptor|TypeDescriptor|ServiceDescriptor|ExtensionFieldDescriptor|ExtensionMapFieldDescriptor);
-
type NamespaceDescriptor = {
+ options?: { [k: string]: any };
+ nested: { [k: string]: AnyNestedDescriptor };
+};
+
+type NamespaceBaseDescriptor = {
options?: { [k: string]: any };
nested?: { [k: string]: AnyNestedDescriptor };
};
+type AnyExtensionFieldDescriptor = (ExtensionFieldDescriptor|ExtensionMapFieldDescriptor);
+
+type AnyNestedDescriptor = (EnumDescriptor|TypeDescriptor|ServiceDescriptor|AnyExtensionFieldDescriptor|NamespaceDescriptor);
+
/**
* Constructs a new reflection object instance.
* @classdesc Base class of all reflection objects.
diff --git a/src/namespace.js b/src/namespace.js
index b9b1e4613..6fd4bfa51 100644
--- a/src/namespace.js
+++ b/src/namespace.js
@@ -98,22 +98,37 @@ Object.defineProperty(Namespace.prototype, "nestedArray", {
});
/**
- * Any nested object descriptor.
- * @typedef AnyNestedDescriptor
- * @type {EnumDescriptor|TypeDescriptor|ServiceDescriptor|ExtensionFieldDescriptor|ExtensionMapFieldDescriptor}
+ * Namespace descriptor.
+ * @typedef NamespaceDescriptor
+ * @type {Object}
+ * @property {Object.} [options] Namespace options
+ * @property {Object.} nested Nested object descriptors
*/
/**
- * Namespace descriptor.
- * @typedef NamespaceDescriptor
+ * Namespace base descriptor.
+ * @typedef NamespaceBaseDescriptor
* @type {Object}
* @property {Object.} [options] Namespace options
* @property {Object.} [nested] Nested object descriptors
*/
+/**
+ * Any extension field descriptor.
+ * @typedef AnyExtensionFieldDescriptor
+ * @type {ExtensionFieldDescriptor|ExtensionMapFieldDescriptor}
+ */
+
+/**
+ * Any nested object descriptor.
+ * @typedef AnyNestedDescriptor
+ * @type {EnumDescriptor|TypeDescriptor|ServiceDescriptor|AnyExtensionFieldDescriptor|NamespaceDescriptor}
+ */
+// ^ BEWARE: VSCode hangs forever when using more than 5 types (that's why AnyExtensionFieldDescriptor exists in the first place)
+
/**
* Converts this namespace to a namespace descriptor.
- * @returns {NamespaceDescriptor} Namespace descriptor
+ * @returns {NamespaceBaseDescriptor} Namespace descriptor
*/
Namespace.prototype.toJSON = function toJSON() {
return {