Skip to content

Instantly share code, notes, and snippets.

@Gerrit0
Created June 9, 2024 16:24
Show Gist options
  • Save Gerrit0/5cebc127fd4b181e49e354b786d181d7 to your computer and use it in GitHub Desktop.
Save Gerrit0/5cebc127fd4b181e49e354b786d181d7 to your computer and use it in GitHub Desktop.
TypeDoc type print width estimation
function aggregate<T>(arr: T[], fn: (item: T) => number) {
return arr.reduce((sum, it) => sum + fn(it), 0);
}
function aggregateWithJoiner<T>(arr: T[], fn: (item: T) => number, joiner: string) {
return arr.reduce((sum, it) => sum + fn(it), 0) + (arr.length - 1) * joiner.length;
}
// Used to check if we should split a union into multiple lines.
export function estimatePrintWidth(type: Type): number {
return type.visit({
array(arr) {
return estimatePrintWidth(arr.elementType) + 2;
},
conditional() {
return Infinity; // Always split into multiple lines, so the union should be too.
},
indexedAccess(t) {
return estimatePrintWidth(t.objectType) + estimatePrintWidth(t.indexType) + 3;
},
inferred(t) {
return t.name.length + "infer ".length;
},
intersection(t) {
return 3 * (t.types.length - 1) + aggregate(t.types, estimatePrintWidth);
},
intrinsic(t) {
return t.name.length;
},
literal(t) {
return t.toString().length;
},
mapped(t) {
let base =
"{ [ in ]: }".length +
t.parameter.length +
estimatePrintWidth(t.parameterType) +
estimatePrintWidth(t.templateType);
if (t.nameType) {
base += " as ".length + estimatePrintWidth(t.nameType);
}
return base;
},
namedTupleMember(t) {
return +t.isOptional + t.name.length + ": ".length + estimatePrintWidth(t.element);
},
optional(t) {
return 1 + estimatePrintWidth(t.elementType);
},
predicate(t) {
let len = t.name.length;
if (t.asserts) len += "asserts ".length;
if (t.targetType) len += " is ".length + estimatePrintWidth(t.targetType);
return len;
},
query(t) {
return "typeof ".length + estimatePrintWidth(t.queryType);
},
reference(t) {
let len = 0;
if (t.reflection) {
const path = getNamespacedPath(t.reflection);
len += aggregateWithJoiner(path, (refl) => refl.name.length, ".");
} else {
len += t.name.length;
}
if (t.typeArguments) {
len += "<>".length + aggregateWithJoiner(t.typeArguments, estimatePrintWidth, ", ");
}
return len;
},
reflection() {
return Infinity;
},
rest(t) {
return "...".length + estimatePrintWidth(t.elementType);
},
templateLiteral(t) {
let len = t.head.length;
len += aggregate(t.tail, (item) => estimatePrintWidth(item[0]) + item[1].length);
return len;
},
tuple(t) {
return "[]".length + aggregateWithJoiner(t.elements, estimatePrintWidth, ", ");
},
typeOperator(t) {
return t.operator.length + 1 + estimatePrintWidth(t.target);
},
union(t) {
return aggregateWithJoiner(t.types, estimatePrintWidth, " | ");
},
unknown(t) {
return t.name.length;
},
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment