Skip to content

Commit

Permalink
feat(check-types): allow two types (set one to the other in `prefer…
Browse files Browse the repository at this point in the history
…redTypes`); make this the default for typescript with "object"/"Object"
  • Loading branch information
brettz9 committed Jul 8, 2020
1 parent 96dcdce commit 82ca868
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .README/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ how the keys of `preferredTypes` may have `<>` or `.<>` (or just `.`)
appended and its bearing on whether types are checked as parents/children
only (e.g., to match `Array` if the type is `Array` vs. `Array.<string>`).

Note that if a value is present both as a key and as a value, neither the
key nor the value will be reported. Thus in `check-types`, this fact can
be used to allow both `object` and `Object` if one has a `preferredTypes`
key `object: 'Object'` and `Object: 'object'`.

## Advanced

### AST and Selectors
Expand Down
5 changes: 5 additions & 0 deletions .README/rules/check-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ RegExp
`string[]` specifically as distinct from say `number[]`, but you can
target both with `[]` or the child types `number` or `string`.

If a value is present both as a key and as a value, neither the key nor the
value will be reported. Thus one can use this fact to allow both `object`
and `Object`, for example. Note that in "typescript" mode, this is the default
behavior.

See also the documentation on `settings.jsdoc.preferredTypes` which impacts
the behavior of `check-types`.

Expand Down
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,11 @@ how the keys of `preferredTypes` may have `<>` or `.<>` (or just `.`)
appended and its bearing on whether types are checked as parents/children
only (e.g., to match `Array` if the type is `Array` vs. `Array.<string>`).

Note that if a value is present both as a key and as a value, neither the
key nor the value will be reported. Thus in `check-types`, this fact can
be used to allow both `object` and `Object` if one has a `preferredTypes`
key `object: 'Object'` and `Object: 'object'`.

<a name="eslint-plugin-jsdoc-advanced"></a>
## Advanced

Expand Down Expand Up @@ -3382,6 +3387,11 @@ RegExp
`string[]` specifically as distinct from say `number[]`, but you can
target both with `[]` or the child types `number` or `string`.

If a value is present both as a key and as a value, neither the key nor the
value will be reported. Thus one can use this fact to allow both `object`
and `Object`, for example. Note that in "typescript" mode, this is the default
behavior.

See also the documentation on `settings.jsdoc.preferredTypes` which impacts
the behavior of `check-types`.

Expand Down Expand Up @@ -3991,6 +4001,18 @@ function quux (foo) {
}
// Settings: {"jsdoc":{"preferredTypes":{"Array.<>":"[]","Array<>":"[]"}}}
// Message: Invalid JSDoc @param "foo" type "Array"; prefer: "[]".

/**
* @typedef {object} foo
*/
function a () {}

/**
* @typedef {Object} foo
*/
function b () {}
// Settings: {"jsdoc":{"mode":"typescript","preferredTypes":{"object":"Object"}}}
// Message: Invalid JSDoc @typedef "foo" type "object"; prefer: "Object".
````

The following patterns are not considered problems:
Expand Down Expand Up @@ -4224,6 +4246,37 @@ function quux () {}
/** @typedef {object<string, string>} foo */
// Settings: {"jsdoc":{"preferredTypes":{"object<>":"Object<>"}}}
// Options: [{"exemptTagContexts":[{"tag":"typedef","types":["object<string, string>"]}]}]

/**
* @typedef {object} foo
*/

/**
* @typedef {Object} foo
*/
// Settings: {"jsdoc":{"preferredTypes":{"object":"Object","Object":"object"}}}

/**
* @typedef {object} foo
*/
function a () {}

/**
* @typedef {Object} foo
*/
function b () {}
// Settings: {"jsdoc":{"preferredTypes":{"object":"Object","Object":"object"}}}

/**
* @typedef {object} foo
*/
function a () {}

/**
* @typedef {Object} foo
*/
function b () {}
// Settings: {"jsdoc":{"mode":"typescript"}}
````


Expand Down
6 changes: 5 additions & 1 deletion src/rules/checkTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ export default iterateJsdoc(({
});
}
}
const directNameMatch = preferredTypes?.[nodeName] !== undefined;
const directNameMatch = preferredTypes?.[nodeName] !== undefined &&
!Object.values(preferredTypes).includes(nodeName);
const unifiedSyntaxParentMatch = parentType && directNameMatch && unifyParentAndChildTypeChecks;
isGenericMatch = isGenericMatch || unifiedSyntaxParentMatch;

Expand Down Expand Up @@ -171,6 +172,9 @@ export default iterateJsdoc(({
}
} else if (!noDefaults && type === 'NAME') {
for (const strictNativeType of strictNativeTypes) {
if (strictNativeType === 'object' && mode === 'typescript') {
continue;
}
if (strictNativeType.toLowerCase() === nodeName.toLowerCase() &&
strictNativeType !== nodeName &&

Expand Down
96 changes: 96 additions & 0 deletions test/rules/assertions/checkTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,44 @@ export default {
},
},
},
{
code: `
/**
* @typedef {object} foo
*/
function a () {}
/**
* @typedef {Object} foo
*/
function b () {}
`,
errors: [
{
line: 3,
message: 'Invalid JSDoc @typedef "foo" type "object"; prefer: "Object".',
},
],
output: `
/**
* @typedef {Object} foo
*/
function a () {}
/**
* @typedef {Object} foo
*/
function b () {}
`,
settings: {
jsdoc: {
mode: 'typescript',
preferredTypes: {
object: 'Object',
},
},
},
},
],
valid: [
{
Expand Down Expand Up @@ -2387,5 +2425,63 @@ export default {
},
},
},
{
code: `
/**
* @typedef {object} foo
*/
/**
* @typedef {Object} foo
*/
`,
settings: {
jsdoc: {
preferredTypes: {
object: 'Object',
Object: 'object',
},
},
},
},
{
code: `
/**
* @typedef {object} foo
*/
function a () {}
/**
* @typedef {Object} foo
*/
function b () {}
`,
settings: {
jsdoc: {
preferredTypes: {
object: 'Object',
Object: 'object',
},
},
},
},
{
code: `
/**
* @typedef {object} foo
*/
function a () {}
/**
* @typedef {Object} foo
*/
function b () {}
`,
settings: {
jsdoc: {
mode: 'typescript',
},
},
},
],
};

0 comments on commit 82ca868

Please sign in to comment.