Repository: lingui/js-lingui (ts)

Issue:
t macro with variable id extracted as message with undefined id
**Describe the bug**
`t({id: foo})` calls are being extracted with `undefined` message id
```po
#~ messages.po

#: src/path/file.tsx:##
msgid "undefined"
msgstr ""
```

**To Reproduce**

```
// src/path/file.tsx

import {t} from "@lingui/macro"

const foo = t`foo`

const Component = () => {
  const text = t({id: foo})

  return <span>{text}</span>
}
```

**Expected behavior**
No `messages.po` changes

**Additional context**
Dependencies

```json
    "@lingui/cli": "3.2.3",
    "@lingui/loader": "3.2.3",
    "@lingui/macro": "3.2.3",
    "@lingui/react": "3.2.3",
    "babel-plugin-macros": "2.8.0",
    "react-scripts": "3.4.3",
    "typescript": "3.9.7",
```

Pull request description:
fix: prevent adding undefined msgid to messages
Changes in `babel-plugin-extract-messages` packages:
- added reproduction test case where undefined msgid is being generated
- added a fix for that test case
- refactored related function a bit

Closes #905

Patch:
diff --git a/packages/babel-plugin-extract-messages/src/index.ts b/packages/babel-plugin-extract-messages/src/index.ts
index dd81c52c..8eaf1bca 100644
--- a/packages/babel-plugin-extract-messages/src/index.ts
+++ b/packages/babel-plugin-extract-messages/src/index.ts
@@ -19,6 +19,9 @@ function addMessage(
   messages,
   { id, message: newDefault, origin, comment, ...props }
 ) {
+  // prevent from adding undefined msgid
+  if (id === undefined) return
+
   if (messages.has(id)) {
     const message = messages.get(id)
 
@@ -27,15 +30,15 @@ function addMessage(
       throw path.buildCodeFrameError(
         "Different defaults for the same message ID."
       )
-    } else {
-      if (newDefault) {
-        message.message = newDefault
-      }
+    }
 
-      ;[].push.apply(message.origin, origin)
-      if (comment) {
-        ;[].push.apply(message.extractedComments, [comment])
-      }
+    if (newDefault) {
+      message.message = newDefault
+    }
+
+    ;[].push.apply(message.origin, origin)
+    if (comment) {
+      ;[].push.apply(message.extractedComments, [comment])
     }
   } else {
     const extractedComments = comment ? [comment] : []


Test patch:
diff --git a/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js b/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js
index f7c1ed96..607eb9c0 100644
--- a/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js
+++ b/packages/babel-plugin-extract-messages/test/fixtures/js-with-macros.js
@@ -20,3 +20,9 @@ const withTId = t({
   id: "ID Some",
   message: "Message with id some"
 })
+
+const id = 'message id'
+
+const withUnknownId = t({
+  id: id
+})