Source:
<code>private void visitEnumType(String symbolName, String qualifiedName, EnumType type, Node node) { String unqualifiedName = getUnqualifiedName(symbolName); String elementsTypeName = type.getElementsType().getReferenceName(); if (qualifiedName.equals(elementsTypeName)) { if (node != null && node.getNext() != null && node.getNext().isGetProp()) { elementsTypeName = node.getNext().getQualifiedName(); } } if (!qualifiedName.equals(elementsTypeName)) { emitComment(symbolName + " aliases enum " + elementsTypeName); emit("type"); emit(unqualifiedName); emit("="); emit(elementsTypeName); emit(";"); emitBreak(); emit("const"); emit(unqualifiedName); emit(": typeof"); emit(elementsTypeName); emit(";"); emitBreak(); return; } Node objectOfAllMembers = node.getNext() != null ? node.getNext() : node.getFirstChild(); Stream<Node> elementStream = Streams.stream(objectOfAllMembers.children()); Map<String, Node> elements = elementStream.collect(Collectors.toMap(Node::getString, Node::getFirstChild)); JSType primitiveType = type.getEnumeratedTypeOfEnumObject(); if (maybeStringOrNumericEnum(primitiveType, unqualifiedName, objectOfAllMembers, elements)) { return; } if (primitiveType.equals(stringType)) { Set<String> literalTypes = collectAllLiterals(elements); visitTypeAlias(primitiveType, unqualifiedName, literalTypes); } else { visitTypeAlias(primitiveType, unqualifiedName, true); } emit("var"); emit(unqualifiedName); emit(": {"); emitBreak(); indent(); for (String elem : sorted(type.getElements())) { emit(elem); emit(":"); Node n = elements.get(elem); if (primitiveType.equals(stringType) && n.isString()) { emit("'" + n.getString() + "'"); } else { <START> emit(unqualifiedName); <END> } emit(","); emitBreak(); } unindent(); emit("}"); emitNoSpace(";"); emitBreak(); }</code><technical_language>this sense if primitiveType != stringType, is this valid closure /** @enum {string|number} */ x = {A: 0, B: "fsds"}</technical_language>

Target:
private void visitEnumType(String symbolName, String qualifiedName, EnumType type, Node node) { String unqualifiedName = getUnqualifiedName(symbolName); String elementsTypeName = type.getElementsType().getReferenceName(); if (qualifiedName.equals(elementsTypeName)) { if (node != null && node.getNext() != null && node.getNext().isGetProp()) { elementsTypeName = node.getNext().getQualifiedName(); } } if (!qualifiedName.equals(elementsTypeName)) { emitComment(symbolName + " aliases enum " + elementsTypeName); emit("type"); emit(unqualifiedName); emit("="); emit(elementsTypeName); emit(";"); emitBreak(); emit("const"); emit(unqualifiedName); emit(": typeof"); emit(elementsTypeName); emit(";"); emitBreak(); return; } Node objectOfAllMembers = node.getNext() != null ? node.getNext() : node.getFirstChild(); Stream<Node> elementStream = Streams.stream(objectOfAllMembers.children()); Map<String, Node> elements = elementStream.collect(Collectors.toMap(Node::getString, Node::getFirstChild)); JSType primitiveType = type.getEnumeratedTypeOfEnumObject(); if (maybeStringOrNumericEnum(primitiveType, unqualifiedName, objectOfAllMembers, elements)) { return; } if (primitiveType.equals(stringType)) { Set<String> literalTypes = collectAllLiterals(elements); visitTypeAliasForMixedStringEnums(primitiveType, unqualifiedName, literalTypes); } else { visitTypeAlias(primitiveType, unqualifiedName, true); } emit("var"); emit(unqualifiedName); emit(": {"); emitBreak(); indent(); for (String elem : sorted(type.getElements())) { emit(elem); emit(":"); Node n = elements.get(elem); if (primitiveType.equals(stringType) && n.isString()) { emit("'" + n.getString() + "'"); } else { emit(unqualifiedName); } emit(","); emitBreak(); } unindent(); emit("}"); emitNoSpace(";"); emitBreak(); }