Skip to content

Commit

Permalink
Merge pull request #1920 from ejuda/support-enum-like-objects-with-nu…
Browse files Browse the repository at this point in the history
…merical-values
  • Loading branch information
Gerrit0 committed Apr 14, 2022
2 parents abed9a6 + 1030769 commit 154ad60
Show file tree
Hide file tree
Showing 4 changed files with 94 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
38 changes: 38 additions & 0 deletions src/test/behaviorTests.ts
Expand Up @@ -39,6 +39,44 @@ export const behaviorTests: Record<

const WithoutReadonly = query(project, "WithoutReadonly");
equal(WithoutReadonly.kind, ReflectionKind.Enum, "WithoutReadonly");

const SomeEnumLikeNumeric = query(project, "SomeEnumLikeNumeric");
equal(
SomeEnumLikeNumeric.kind,
ReflectionKind.Variable,
"SomeEnumLikeNumeric"
);
const SomeEnumLikeTaggedNumeric = query(
project,
"SomeEnumLikeTaggedNumeric"
);
equal(
SomeEnumLikeTaggedNumeric.kind,
ReflectionKind.Enum,
"SomeEnumLikeTaggedNumeric"
);
const B = query(project, "SomeEnumLikeTaggedNumeric.b");
equal(B.defaultValue, "1");

const ManualEnumNumeric = query(project, "ManualEnumNumeric");
equal(ManualEnumNumeric.kind, ReflectionKind.Enum, "ManualEnumNumeric");

const ManualWithoutHelperNumeric = query(
project,
"ManualEnumHelperNumeric"
);
equal(
ManualWithoutHelperNumeric.kind,
ReflectionKind.Enum,
"ManualEnumHelperNumeric"
);

const WithoutReadonlyNumeric = query(project, "WithoutReadonlyNumeric");
equal(
WithoutReadonlyNumeric.kind,
ReflectionKind.Enum,
"WithoutReadonlyNumeric"
);
},
duplicateHeritageClauses(project) {
const b = query(project, "B");
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 154ad60

Please sign in to comment.