Skip to content

Commit d46b285

Browse files
committed
fix: for "typescript" mode, require object shorthand or index signatures; fixes gajus#1001
BREAKING CHANGE: For typescript mode, one must use object shorthand or index signatures, e.g., `{[key: string]: number}` or `{a: string, b: number}`
1 parent 33628b4 commit d46b285

File tree

4 files changed

+51
-26
lines changed

4 files changed

+51
-26
lines changed

.README/rules/check-types.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ object.
103103

104104
However, `Object.create(null)` objects are not `instanceof Object`, however, so
105105
in the case of such a plain object we lower-case to indicate possible support
106-
for these objects. Also, nowadays, TypeScript also discourages use of `Object`
106+
for these objects. Also, nowadays, TypeScript also [discourages](https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#:~:text=%E2%9D%8C%20Don't%20ever%20use,used%20appropriately%20in%20JavaScript%20code.)
107+
use of `Object`
107108
as a lone type. However, one additional complexity is that TypeScript allows and
108109
actually [currently requires](https://github.com/microsoft/TypeScript/issues/20555)
109110
`Object` (with the initial upper-case) if used in the syntax
@@ -112,8 +113,14 @@ adhere to that which [JSDoc documents](https://jsdoc.app/tags-type.html).
112113

113114
So, for optimal compatibility with TypeScript (especially since TypeScript
114115
tools can be used on plain JavaScript with JSDoc), we are now requiring this
115-
TypeScript approach by default (if you set `object` type `preferredTypes` in
116-
TypeScript mode, the defaults will not apply).
116+
TypeScript approach by default in non-"typescript" mode (if you set
117+
`object` type `preferredTypes` in TypeScript mode, the defaults will
118+
not apply).
119+
120+
However, for "typescript" mode, a still better choice exists—using index signatures such as `{[key: string]: string}` or using a more precise
121+
shorthand object syntax (e.g., `{a: string, b: number}`). This is superior
122+
for TypeScript because the likes of `Object<string, number>` is not useable
123+
in native TypeScript syntax, even if it is allowed within JSDoc.
117124

118125
Basically, for primitives, we want to define the type as a primitive, because
119126
that's what we use in 99.9% of cases. For everything else, we use the type

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5442,7 +5442,8 @@ object.
54425442

54435443
However, `Object.create(null)` objects are not `instanceof Object`, however, so
54445444
in the case of such a plain object we lower-case to indicate possible support
5445-
for these objects. Also, nowadays, TypeScript also discourages use of `Object`
5445+
for these objects. Also, nowadays, TypeScript also [discourages](https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#:~:text=%E2%9D%8C%20Don't%20ever%20use,used%20appropriately%20in%20JavaScript%20code.)
5446+
use of `Object`
54465447
as a lone type. However, one additional complexity is that TypeScript allows and
54475448
actually [currently requires](https://github.com/microsoft/TypeScript/issues/20555)
54485449
`Object` (with the initial upper-case) if used in the syntax
@@ -5451,8 +5452,14 @@ adhere to that which [JSDoc documents](https://jsdoc.app/tags-type.html).
54515452

54525453
So, for optimal compatibility with TypeScript (especially since TypeScript
54535454
tools can be used on plain JavaScript with JSDoc), we are now requiring this
5454-
TypeScript approach by default (if you set `object` type `preferredTypes` in
5455-
TypeScript mode, the defaults will not apply).
5455+
TypeScript approach by default in non-"typescript" mode (if you set
5456+
`object` type `preferredTypes` in TypeScript mode, the defaults will
5457+
not apply).
5458+
5459+
However, for "typescript" mode, a still better choice exists—using index signatures such as `{[key: string]: string}` or using a more precise
5460+
shorthand object syntax (e.g., `{a: string, b: number}`). This is superior
5461+
for TypeScript because the likes of `Object<string, number>` is not useable
5462+
in native TypeScript syntax, even if it is allowed within JSDoc.
54565463

54575464
Basically, for primitives, we want to define the type as a primitive, because
54585465
that's what we use in 99.9% of cases. For everything else, we use the type
@@ -6132,7 +6139,7 @@ function quux (foo) {
61326139

61336140
}
61346141
// Settings: {"jsdoc":{"mode":"typescript"}}
6135-
// Message: Invalid JSDoc @param "foo" type "object"; prefer: "Object<>".
6142+
// Message: Use object shorthand or index signatures instead of `object`, e.g., `{[key: string]: string}`
61366143

61376144
/**
61386145
*
@@ -6414,7 +6421,7 @@ function b () {}
64146421
function a () {}
64156422

64166423
/**
6417-
* @typedef {Object<string>} foo
6424+
* @typedef {{[key: string]: number}} foo
64186425
*/
64196426
function b () {}
64206427
// Settings: {"jsdoc":{"mode":"typescript"}}
@@ -6443,7 +6450,7 @@ function quux (foo) {
64436450
}
64446451

64456452
/**
6446-
* @param {Object<string>} foo
6453+
* @param {{[key: string]: number}} foo
64476454
*/
64486455
function quux (foo) {
64496456

src/rules/checkTypes.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,32 @@ export default iterateJsdoc(({
9797
'Object.<>' in preferredTypesOriginal ||
9898
'object<>' in preferredTypesOriginal);
9999

100-
const preferredTypes = {
101-
...injectObjectPreferredTypes ? {
100+
const message = 'Use object shorthand or index signatures instead of ' +
101+
'`object`, e.g., `{[key: string]: string}`';
102+
const info = {
103+
message,
104+
replacement: false,
105+
};
106+
107+
const typeToInject = mode === 'typescript' ?
108+
{
109+
Object: 'object',
110+
'object.<>': info,
111+
'Object.<>': info,
112+
'object<>': info,
113+
'Object<>': info,
114+
} :
115+
{
102116
Object: 'object',
103117
'object.<>': 'Object<>',
104118
'Object.<>': 'Object<>',
105119
'object<>': 'Object<>',
106-
} : {},
120+
};
121+
122+
const preferredTypes = {
123+
...injectObjectPreferredTypes ?
124+
typeToInject :
125+
{},
107126
...preferredTypesOriginal,
108127
};
109128

@@ -364,7 +383,7 @@ export default iterateJsdoc(({
364383
for (const [
365384
badType,
366385
preferredType = '',
367-
message,
386+
msg,
368387
] of invalidTypes) {
369388
const tagValue = jsdocTag.name ? ` "${jsdocTag.name}"` : '';
370389
if (exemptTagContexts.some(({
@@ -378,13 +397,13 @@ export default iterateJsdoc(({
378397
}
379398

380399
report(
381-
message ||
400+
msg ||
382401
`Invalid JSDoc @${tagName}${tagValue} type "${badType}"` +
383402
(preferredType ? '; ' : '.') +
384403
(preferredType ? `prefer: ${JSON.stringify(preferredType)}.` : ''),
385404
preferredType ? fix : null,
386405
jsdocTag,
387-
message ? {
406+
msg ? {
388407
tagName,
389408
tagValue,
390409
} : null,

test/rules/assertions/checkTypes.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,17 +2339,9 @@ export default {
23392339
errors: [
23402340
{
23412341
line: 3,
2342-
message: 'Invalid JSDoc @param "foo" type "object"; prefer: "Object<>".',
2342+
message: 'Use object shorthand or index signatures instead of `object`, e.g., `{[key: string]: string}`',
23432343
},
23442344
],
2345-
output: `
2346-
/**
2347-
* @param {Object<string>} foo
2348-
*/
2349-
function quux (foo) {
2350-
2351-
}
2352-
`,
23532345
settings: {
23542346
jsdoc: {
23552347
mode: 'typescript',
@@ -2944,7 +2936,7 @@ export default {
29442936
function a () {}
29452937
29462938
/**
2947-
* @typedef {Object<string>} foo
2939+
* @typedef {{[key: string]: number}} foo
29482940
*/
29492941
function b () {}
29502942
`,
@@ -3020,7 +3012,7 @@ export default {
30203012
{
30213013
code: `
30223014
/**
3023-
* @param {Object<string>} foo
3015+
* @param {{[key: string]: number}} foo
30243016
*/
30253017
function quux (foo) {
30263018

0 commit comments

Comments
 (0)