Skip to content

Commit

Permalink
Support enum-like objects with numeric literal values
Browse files Browse the repository at this point in the history
TypeDoc already supports enum-like objects with string literal values
via TypeStrong#1675 and TypeStrong#1740. Enum-like objects with numeric literal values
should also be supported, as they are a popular choice for developers
wishing to avoid use of TypeScript enums.

This PR adds support for such objects. Tests and a new example have
been added to cover this type of object.

Resolves TypeStrong#1918.
  • Loading branch information
ejuda committed Apr 12, 2022
1 parent abed9a6 commit 8b34045
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
24 changes: 24 additions & 0 deletions example/src/enums.ts
Expand Up @@ -51,3 +51,27 @@ export const EnumLikeObject = {

Completed: "completed",
} as const;

/**
* Since TypeScript's `enum` can be inconvenient to work with, some packages define their own enum-like objects:
*
* ```
* export const EnumLikeObjectNumValues = {
* Pending: 1,
* InProgress: 2,
* Completed: 3
* } as const
* ```
*
* Use the `@enum` tag to make TypeDoc document this object as an enum.
*
* @enum
*/
export const EnumLikeObjectNumValues = {
Pending: 1,

/** Indicates that a courier is en route delivering this order. */
InProgress: 2,

Completed: 3,
} as const;
4 changes: 2 additions & 2 deletions src/lib/converter/symbols.ts
Expand Up @@ -881,7 +881,7 @@ function isEnumLike(checker: ts.TypeChecker, type: ts.Type, location: ts.Node) {

return type.getProperties().every((prop) => {
const propType = checker.getTypeOfSymbolAtLocation(prop, location);
return propType.isStringLiteral();
return propType.isStringLiteral() || propType.isNumberLiteral();
});
}

Expand Down Expand Up @@ -912,7 +912,7 @@ function convertVariableAsEnum(
prop,
declaration
);
assert(propType.isStringLiteral());
assert(propType.isStringLiteral() || propType.isNumberLiteral());

reflection.defaultValue = JSON.stringify(propType.value);

Expand Down
30 changes: 30 additions & 0 deletions src/test/converter2/behavior/asConstEnum.ts
@@ -1,3 +1,5 @@
/* Enum-like objects with string literal values */

export const SomeEnumLike = {
a: "a",
b: "b",
Expand All @@ -23,3 +25,31 @@ export const ManualEnumHelper: Readonly<{ a: "a" }> = {
export const WithoutReadonly = {
a: "a",
} as { a: "a" };

/* Enum-like objects with numeric literal values */

export const SomeEnumLikeNumeric = {
a: 0,
b: 1,
} as const;

/** @enum */
export const SomeEnumLikeTaggedNumeric = {
a: 0,
b: 1,
} as const;

/** @enum */
export const ManualEnumNumeric: { readonly a: 0 } = {
a: 0,
};

/** @enum */
export const ManualEnumHelperNumeric: Readonly<{ a: 0 }> = {
a: 0,
};

/** @enum */
export const WithoutReadonlyNumeric = {
a: 0,
} as { a: 0 };

0 comments on commit 8b34045

Please sign in to comment.