Skip to content

Commit

Permalink
Introduce createEnumSubset method on EnumWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
UselessPickles committed Apr 12, 2024
1 parent b236360 commit c8ef4a1
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 0 deletions.
29 changes: 29 additions & 0 deletions docs/EnumWrapper.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ Usage documentation for the `EnumWrapper` portion of `ts-enum-util`.
- [Lookup Value by Key](#lookup-value-by-key)
- [EnumWrapper.prototype.getValueOrThrow](#enumwrapperprototypegetvalueorthrow)
- [EnumWrapper.prototype.getValueOrDefault](#enumwrapperprototypegetvalueordefault)
- [Create a new enum-like object with a subset of an enum's entries](#create-a-new-enum-like-object-with-a-subset-of-an-enums-entries)
- [EnumWrapper.prototype.createEnumSubset](#enumwrapperprototypecreateenumsubset)

<!-- /TOC -->

Expand Down Expand Up @@ -819,3 +821,30 @@ EnumWrapper.prototype.getValueOrDefault(
defaultValue?: EnumType | ValueType
): EnumType | ValueType | undefined
```

### Create a new enum-like object with a subset of an enum's entries

#### EnumWrapper.prototype.createEnumSubset

Use this method to create a new well-typed [Enum-Like Object](#enum-like-object) that contains
a subset of entries from the original enum.

```ts
EnumWrapper.prototype.createEnumSubset(
...keys: readonly KeyType[]
): EnumLike
```

Example:

```ts
enum Numbers {
One = 1,
Two = 2,
Three = 3,
Four = 4
}

const EvenNumbers = $enum(Numbers).createEnumSubset("Two", "Four");
type EvenNumbers = typeof EvenNumbers[keyof typeof EvenNumbers];
```
15 changes: 15 additions & 0 deletions src/EnumWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,21 @@ export class EnumWrapper<
return defaultValue;
}
}

/**
* Creates an enum-like object that contains a subset of entries of the
* original enum.
* @param keys - The keys to include in the new enum-like object.
* @returns A new enum-like object.
*/
public createEnumSubset<K extends StringKeyOf<T>>(
...keys: readonly K[]
): Pick<T, K> {
return keys.reduce<Record<string, T[K]>>((result, key) => {
result[key] = this.enumObj[key];
return result;
}, {}) as Pick<T, K>;
}
}

// HACK: Forcefully overriding the value of the [Symbol.toStringTag] property.
Expand Down
7 changes: 7 additions & 0 deletions tests/EnumWrapper-mixed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,4 +542,11 @@ describe("EnumWrapper: number+string enum", () => {
);
expect(enumWrapper.getValueOrDefault(undefined, -1)).toBe(-1);
});

test("createEnumSubset()", () => {
expect(enumWrapper.createEnumSubset("A", "C")).toEqual({
A: TestEnum.A,
C: TestEnum.C
});
});
});
7 changes: 7 additions & 0 deletions tests/EnumWrapper-number.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,4 +524,11 @@ describe("EnumWrapper: string enum", () => {
);
expect(enumWrapper.getValueOrDefault(undefined, -1)).toBe(-1);
});

test("createEnumSubset()", () => {
expect(enumWrapper.createEnumSubset("A", "C")).toEqual({
A: TestEnum.A,
C: TestEnum.C
});
});
});
7 changes: 7 additions & 0 deletions tests/EnumWrapper-string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,4 +531,11 @@ describe("EnumWrapper: string enum", () => {
);
expect(enumWrapper.getValueOrDefault(undefined, "foo")).toBe("foo");
});

test("createEnumSubset()", () => {
expect(enumWrapper.createEnumSubset("A", "C")).toEqual({
A: TestEnum.A,
C: TestEnum.C
});
});
});
3 changes: 3 additions & 0 deletions type_tests/v2_9_plus/EnumWrapper/enum-mixed.dtslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,6 @@ enumWrapper.getValueOrDefault(str, str);
enumWrapper.getValueOrDefault(str, numstr);
// $ExpectType string | number | undefined
enumWrapper.getValueOrDefault(str, numstrOrUndefined);

// $ExpectType Pick<typeof TestEnum, "A" | "C">
enumWrapper.createEnumSubset("A", "C");
3 changes: 3 additions & 0 deletions type_tests/v2_9_plus/EnumWrapper/enum-number.dtslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,6 @@ enumWrapper.getValueOrDefault(str, num);
enumWrapper.getValueOrDefault(str, numOrUndefined);
// $ExpectError
enumWrapper.getValueOrDefault(str, str);

// $ExpectType Pick<typeof TestEnum, "A" | "C">
enumWrapper.createEnumSubset("A", "C");
3 changes: 3 additions & 0 deletions type_tests/v2_9_plus/EnumWrapper/enum-string.dtslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,6 @@ enumWrapper.getValueOrDefault(str, str);
enumWrapper.getValueOrDefault(str, strOrUndefined);
// $ExpectError
enumWrapper.getValueOrDefault(str, num);

// $ExpectType Pick<typeof TestEnum, "A" | "C">
enumWrapper.createEnumSubset("A", "C");

0 comments on commit c8ef4a1

Please sign in to comment.