(literalType: ts.TypeLiteralNode, typeChecker: ts.TypeChecker)
| 125 | }; |
| 126 | |
| 127 | function computePropertiesForLiteralType(literalType: ts.TypeLiteralNode, typeChecker: ts.TypeChecker) { |
| 128 | const properties: TelemetryProperty[] = []; |
| 129 | |
| 130 | literalType.members.forEach((m) => { |
| 131 | if (m.kind === ts.SyntaxKind.PropertySignature && ts.isPropertySignature(m)) { |
| 132 | const name = m.name.getText(); |
| 133 | const anyM = m as unknown as { jsDoc?: { comment: string }[] }; |
| 134 | const descriptions = Array.isArray(anyM.jsDoc) ? anyM.jsDoc[0].comment.split(/\r?\n/) || [] : []; |
| 135 | let possibleValues: { value: string; comment?: string | string[] }[] = []; |
| 136 | let typeValue = ''; |
| 137 | if ( |
| 138 | (m.type?.kind === ts.SyntaxKind.TypeReference && ts.isTypeReferenceNode(m.type)) || |
| 139 | (m.type?.kind === ts.SyntaxKind.UnionType && ts.isUnionTypeNode(m.type)) |
| 140 | ) { |
| 141 | const type = typeChecker.getTypeAtLocation(m.type); |
| 142 | if (type.isUnion()) { |
| 143 | const isEnum = type |
| 144 | .getSymbol() |
| 145 | ?.getDeclarations() |
| 146 | ?.some((d) => d.kind === ts.SyntaxKind.EnumDeclaration); |
| 147 | const enumName = type.getSymbol()?.escapedName; |
| 148 | type.types.forEach((t) => { |
| 149 | if (t.isLiteral()) { |
| 150 | const value = t.value.toString(); |
| 151 | const declaration = t.symbol?.declarations?.length |
| 152 | ? (t.symbol.declarations[0] as unknown as { jsDoc?: { comment: string }[] }) |
| 153 | : undefined; |
| 154 | const comment = []; |
| 155 | if (isEnum && parseInt(value, 10).toString() === value.trim()) { |
| 156 | comment.push(`Enum Member: ${enumName}.${t.symbol.escapedName}`); |
| 157 | } |
| 158 | if (declaration && Array.isArray(declaration.jsDoc) && declaration.jsDoc.length > 0) { |
| 159 | comment.push(declaration.jsDoc[0].comment); |
| 160 | } |
| 161 | possibleValues.push({ value, comment }); |
| 162 | } |
| 163 | }); |
| 164 | } |
| 165 | const mType = m.type; |
| 166 | if ( |
| 167 | mType.kind === ts.SyntaxKind.UnionType && |
| 168 | ts.isUnionTypeNode(mType) && |
| 169 | possibleValues.every((item) => (item.comment || '').length === 0) |
| 170 | ) { |
| 171 | // Support comments in union string literals. |
| 172 | const newPossibleValues: { value: string; comment?: string | string[] }[] = []; |
| 173 | mType.types.forEach((t) => { |
| 174 | if (t.kind === ts.SyntaxKind.LiteralType) { |
| 175 | const value = t.getText(); |
| 176 | const comment = getCommentForUnions(t); |
| 177 | newPossibleValues.push({ value, comment }); |
| 178 | } else if (t.kind === ts.SyntaxKind.NullKeyword || t.kind === ts.SyntaxKind.UndefinedKeyword) { |
| 179 | newPossibleValues.push({ value: 'null or <empty>', comment: '' }); |
| 180 | } else if (t.kind === ts.SyntaxKind.BooleanKeyword) { |
| 181 | newPossibleValues.push({ value: 'true', comment: '' }); |
| 182 | newPossibleValues.push({ value: 'false', comment: '' }); |
| 183 | } |
| 184 | }); |
no test coverage detected