TypeScript: Fixed keyword false positives (#3001)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
diff --git a/components/prism-typescript.js b/components/prism-typescript.js
index 199f8d5..7e9ff7b 100644
--- a/components/prism-typescript.js
+++ b/components/prism-typescript.js
@@ -14,8 +14,9 @@
Prism.languages.typescript.keyword.push(
/\b(?:abstract|as|declare|implements|is|keyof|readonly|require)\b/,
// keywords that have to be followed by an identifier
- // eslint-disable-next-line regexp/no-dupe-characters-character-class
- /\b(?:asserts|infer|interface|module|namespace|type)(?!\s*[^\s_${}*a-zA-Z\xA0-\uFFFF])/
+ /\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,
+ // This is for `import type *, {}`
+ /\btype\b(?=\s*(?:[\{*]|$))/
);
// doesn't work with TS because TS is too complex
diff --git a/components/prism-typescript.min.js b/components/prism-typescript.min.js
index 84d1d37..77421b7 100644
--- a/components/prism-typescript.min.js
+++ b/components/prism-typescript.min.js
@@ -1 +1 @@
-!function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|as|declare|implements|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)(?!\s*[^\s_${}*a-zA-Z\xA0-\uFFFF])/),delete e.languages.typescript.parameter;var s=e.languages.extend("typescript",{});delete s["class-name"],e.languages.typescript["class-name"].inside=s,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:s}}}}),e.languages.ts=e.languages.typescript}(Prism);
\ No newline at end of file
+!function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|as|declare|implements|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter;var s=e.languages.extend("typescript",{});delete s["class-name"],e.languages.typescript["class-name"].inside=s,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:s}}}}),e.languages.ts=e.languages.typescript}(Prism);
\ No newline at end of file
diff --git a/tests/languages/typescript/issue3000.test b/tests/languages/typescript/issue3000.test
new file mode 100644
index 0000000..0617bd2
--- /dev/null
+++ b/tests/languages/typescript/issue3000.test
@@ -0,0 +1,51 @@
+import { infer, inference, infer } from 'module'
+// ~~~~~ ✅
+
+import { type, typeDefs, type } from 'module'
+// ~~~~ ✅
+
+import { const, constants, const } from 'module'
+// ~~~~~ ✅
+
+----------------------------------------------------
+
+[
+ ["keyword", "import"],
+ ["punctuation", "{"],
+ " infer",
+ ["punctuation", ","],
+ " inference",
+ ["punctuation", ","],
+ " infer ",
+ ["punctuation", "}"],
+ ["keyword", "from"],
+ ["string", "'module'"],
+
+ ["comment", "// ~~~~~ ✅"],
+
+ ["keyword", "import"],
+ ["punctuation", "{"],
+ " type",
+ ["punctuation", ","],
+ " typeDefs",
+ ["punctuation", ","],
+ " type ",
+ ["punctuation", "}"],
+ ["keyword", "from"],
+ ["string", "'module'"],
+
+ ["comment", "// ~~~~ ✅"],
+
+ ["keyword", "import"],
+ ["punctuation", "{"],
+ ["keyword", "const"],
+ ["punctuation", ","],
+ " constants",
+ ["punctuation", ","],
+ ["keyword", "const"],
+ ["punctuation", "}"],
+ ["keyword", "from"],
+ ["string", "'module'"],
+
+ ["comment", "// ~~~~~ ✅"]
+]