• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview Really small utility functions that didn't deserve their own files
3 */
4
5import {
6  AST_NODE_TYPES,
7  TSESLint,
8  TSESTree,
9} from '@typescript-eslint/experimental-utils';
10
11/**
12 * Check if the context file name is *.d.ts or *.d.tsx
13 */
14function isDefinitionFile(fileName: string): boolean {
15  return /\.d\.tsx?$/i.test(fileName || '');
16}
17
18/**
19 * Upper cases the first character or the string
20 */
21function upperCaseFirst(str: string): string {
22  return str[0].toUpperCase() + str.slice(1);
23}
24
25/** Return true if both parameters are equal. */
26type Equal<T> = (a: T, b: T) => boolean;
27
28function arraysAreEqual<T>(
29  a: T[] | undefined,
30  b: T[] | undefined,
31  eq: (a: T, b: T) => boolean,
32): boolean {
33  return (
34    a === b ||
35    (a !== undefined &&
36      b !== undefined &&
37      a.length === b.length &&
38      a.every((x, idx) => eq(x, b[idx])))
39  );
40}
41
42/** Returns the first non-`undefined` result. */
43function findFirstResult<T, U>(
44  inputs: T[],
45  getResult: (t: T) => U | undefined,
46): U | undefined {
47  for (const element of inputs) {
48    const result = getResult(element);
49    if (result !== undefined) {
50      return result;
51    }
52  }
53  return undefined;
54}
55
56/**
57 * Gets a string representation of the name of the index signature.
58 */
59function getNameFromIndexSignature(node: TSESTree.TSIndexSignature): string {
60  const propName: TSESTree.PropertyName | undefined = node.parameters.find(
61    (parameter: TSESTree.Parameter): parameter is TSESTree.Identifier =>
62      parameter.type === AST_NODE_TYPES.Identifier,
63  );
64  return propName ? propName.name : '(index signature)';
65}
66
67/**
68 * Gets a string name representation of the name of the given MethodDefinition
69 * or ClassProperty node, with handling for computed property names.
70 */
71function getNameFromMember(
72  member:
73    | TSESTree.MethodDefinition
74    | TSESTree.TSMethodSignature
75    | TSESTree.TSAbstractMethodDefinition
76    | TSESTree.ClassProperty
77    | TSESTree.TSAbstractClassProperty
78    | TSESTree.Property
79    | TSESTree.TSPropertySignature,
80  sourceCode: TSESLint.SourceCode,
81): string {
82  if (member.key.type === AST_NODE_TYPES.Identifier) {
83    return member.key.name;
84  }
85  if (member.key.type === AST_NODE_TYPES.Literal) {
86    return `${member.key.value}`;
87  }
88
89  return sourceCode.text.slice(...member.key.range);
90}
91
92type ExcludeKeys<
93  TObj extends Record<string, unknown>,
94  TKeys extends keyof TObj
95> = { [k in Exclude<keyof TObj, TKeys>]: TObj[k] };
96type RequireKeys<
97  TObj extends Record<string, unknown>,
98  TKeys extends keyof TObj
99> = ExcludeKeys<TObj, TKeys> & { [k in TKeys]-?: Exclude<TObj[k], undefined> };
100
101function getEnumNames<T extends string>(myEnum: Record<T, unknown>): T[] {
102  return Object.keys(myEnum).filter(x => isNaN(parseInt(x))) as T[];
103}
104
105export {
106  arraysAreEqual,
107  Equal,
108  ExcludeKeys,
109  findFirstResult,
110  getEnumNames,
111  getNameFromIndexSignature,
112  getNameFromMember,
113  isDefinitionFile,
114  RequireKeys,
115  upperCaseFirst,
116};
117