-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.ts
51 lines (38 loc) · 1.41 KB
/
util.ts
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
import {CallExpression, Node, Type, TypeChecker} from '@tsd/typescript';
import {Diagnostic} from '../../interfaces';
import {makeDiagnostic} from '../../utils';
type MaybeTypes =
| {type: Type | undefined; argument: Node; diagnostic?: never}
| {diagnostic: Diagnostic; type?: never; argument?: never};
export function tryToGetTypes(node: CallExpression, checker: TypeChecker): MaybeTypes {
let type: Type | undefined;
let value: Type | undefined;
const typeArgument = node.typeArguments?.[0];
const valueArgument = node.arguments[0];
if (typeArgument) {
type = checker.getTypeFromTypeNode(typeArgument);
}
if (valueArgument) {
value = checker.getTypeAtLocation(valueArgument);
}
if (type && value) {
return {diagnostic: makeDiagnostic(typeArgument ?? node, 'Do not provide a generic type and an argument value at the same time.')};
}
if (type && typeArgument) {
return {type, argument: typeArgument};
}
return {type: value, argument: valueArgument};
}
type Types =
| {type: Type; argument: Node; diagnostic?: never}
| {diagnostic: Diagnostic; type?: never; argument?: never};
export function getTypes(node: CallExpression, checker: TypeChecker): Types {
const {type, argument, diagnostic} = tryToGetTypes(node, checker);
if (diagnostic) {
return {diagnostic};
}
if (!type) {
return {diagnostic: makeDiagnostic(node, 'A generic type or an argument value is required.')};
}
return {type, argument};
}