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