forked from typescript-eslint/typescript-eslint
/
await-promise.js
92 lines (82 loc) · 2.24 KB
/
await-promise.js
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
83
84
85
86
87
88
89
90
91
92
/**
* @fileoverview Disallows awaiting a value that is not a Promise
* @author Josh Goldberg
*/
'use strict';
const util = require('../util');
const types = require('../utils/types');
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
const defaultOptions = [
{
allowedPromiseNames: []
}
];
/**
* @type {import("eslint").Rule.RuleModule}
*/
module.exports = {
meta: {
docs: {
description: 'Disallows awaiting a value that is not a Promise',
category: 'Functionality',
recommended: 'error',
extraDescription: [util.tslintRule('await-promise')],
url: util.metaDocsUrl('await-promise')
},
fixable: null,
messages: {
await: 'Invalid `await` of a non-Promise value.',
forOf: 'Invalid `for-await-of` of a non-AsyncIterable value.'
},
schema: [
{
type: 'object',
properties: {
allowedPromiseNames: {
type: 'array',
items: {
type: 'string'
}
}
},
additionalProperties: false
}
],
type: 'problem'
},
create(context) {
const options = util.applyDefault(defaultOptions, context.options)[0];
const allowedAsyncIterableNames = new Set([
'AsyncIterable',
'AsyncIterableIterator'
]);
const allowedPromiseNames = new Set([
'Promise',
...options.allowedPromiseNames
]);
const parserServices = util.getParserServices(context);
const checker = parserServices.program.getTypeChecker();
function validateNode(node, allowedSymbolNames, messageId) {
const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node);
const type = checker.getTypeAtLocation(originalNode.expression);
if (!types.containsTypeByName(type, allowedSymbolNames)) {
context.report({
messageId,
node
});
}
}
return {
AwaitExpression(node) {
validateNode(node, allowedPromiseNames, 'await');
},
ForOfStatement(node) {
if (node.await) {
validateNode(node, allowedAsyncIterableNames, 'forOf');
}
}
};
}
};