Skip to content

Commit

Permalink
feat(type): support lower/mixed case as identifier for enum values
Browse files Browse the repository at this point in the history
```typescript
enum Units {
    MILLIGRAM = 'm',
    GRAM = 'g',
}

expect(cast<Units>('MILLIGRAM')).toBe(Units.MILLIGRAM);
expect(cast<Units>('MilLiGrAm')).toBe(Units.MILLIGRAM);
```
  • Loading branch information
marcj committed May 4, 2024
1 parent 0216af4 commit ce0166e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/type/src/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1977,7 +1977,15 @@ export class Serializer {
this.serializeRegistry.register(ReflectionKind.enum, (type, state) => state.addSetter(state.accessor));
this.deserializeRegistry.register(ReflectionKind.enum, (type, state) => {
const valuesVar = state.setVariable('values', type.values);
const lowercaseNames = state.setVariable('lowercaseNames', Object.keys(type.enum).map(v => v.toLowerCase()));
const allLowercased = Object.keys(type.enum).every(v => v.toLowerCase() === v);
const enumValues = state.setVariable('enumValues', type.values);
const allowLowercase = allLowercased ? '' : `
${state.accessor} = ${enumValues}[${lowercaseNames}.indexOf(String(${state.accessor}).toLowerCase())] ?? ${state.accessor};
`;

state.addCodeForSetter(`
${allowLowercase}
${state.setter} = ${state.accessor};
if (${valuesVar}.indexOf(${state.accessor}) === -1) ${state.throwCode('enum', `'No valid value of ' + ${valuesVar}.join(', ')`)}
`);
Expand Down
16 changes: 16 additions & 0 deletions packages/type/tests/serializer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,22 @@ test('naming strategy camel case', () => {
}
});

test('enum mixed case', () => {
enum Units {
MILLIGRAM = 'm',
GRAM = 'g',
KILOGRAM = 'k',
}

expect(cast<Units>('milligram')).toBe('m');
expect(cast<Units>('milligram')).toBe(Units.MILLIGRAM);

expect(cast<Units>('MilliGRAM')).toBe(Units.MILLIGRAM);

expect(cast<Units>('gram')).toBe('g');
expect(cast<Units>('gram')).toBe(Units.GRAM);
});

test('enum union', () => {
enum StatEnginePowerUnit {
Hp = 'hp',
Expand Down

0 comments on commit ce0166e

Please sign in to comment.