Original exercise repo: https://github.com/hurricanenara/enums_exercise
My solution: https://github.com/jbae9/enums_exercise
The following are what I learned and issues I had while solving the exercise.
in
expressionThe in
expression in Javascript returns true
or false
if the property belongs to the object.
When used in a Typescript type, the property of the type can be declared as properties of an enum.
enum Status {
Initialized = "Initialized",
Pending = "Pending",
Complete = "Complete",
}
type StatusObject = {
[key in Status]: key
}
keyof
and typeof
How to use keyof
and typeof
: https://inpa.tistory.com/entry/TS-%F0%9F%93%98-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-keyof-typeof-%EC%82%AC%EC%9A%A9%EB%B2%95
The typeof
operator returns the type from an object value.
const obj = {
red: 'apple',
yellow: 'banana',
green: 'cucumber',
};
// 위의 객체를 타입으로 변환하여 사용하고 싶을때
type Fruit = typeof obj;
/*
type Fruit = {
red: string;
yellow: string;
green: string;
}
*/
The keyof
operator returns a union of properties of a type.
type Type = {
name: string;
age: number;
married: boolean;
}
type Union = keyof Type;
// type Union = name | age | married
Use the keyof typeof
to use a union of properties of an enum.
enum Color {
Red,
Blue,
Black,
}
enum Car {
Sedan,
Truck,
Coupe,
}
type Inventory = {
[key in keyof typeof Car]: keyof typeof Color
}
// type Inventory = {
// [x: number]: "Red" | "Blue | "Black";
// readonly Sedan: "Red" | "Blue | "Black";
// readonly Truck: "Red" | "Blue | "Black";
// readonly Coupe: "Red" | "Blue | "Black"'
//}
// ---------------------------
enum Status {
Initialized = "Initialized",
Pending = "Pending",
Complete = "Complete",
}
type StatusObject = {
[key in Status]: key
}
// type StatusObject = {
// Initialized: Status.Initialized;
// Pending: Status.Pending;
// Complete: Status.Complete;
//}
Object.entries()
Object.entries
returns the [key, value][]
of an object.
For an enum such as Status above, Object.entries(Status)
will return [string,Status][]
.
The returned array can be used to call the array reduce()
function to reformat the object into the desired manner.
enum Status {
Initialized = "Initialized",
Pending = "Pending",
Complete = "Complete",
}
type StatusObject = {
[key in Status]: key
}
// Function that returns
// {
// Initialized: "initialized",
// Pending: "pending",
// Complete: "complete",
// }
function getStatusObject():StatusObject {
// Object.entries() returns [string, Status][], so the
let statusObject: StatusObject = Object.entries(Status).reduce((acc, [_str, status]) =>
// This uses a spread operator to create the object
// However, using a spread operator inside the reduce function is discouraged
// as reduce() runs through the Object.entries() array, then the spread operator runs through the object to be created, increasing time complexity from O(n) to O(n^2)
({...acc, [status]: status.toLowerCase()}), {} as StatusObject)
return statusObject
}
// This function is the same as above without using the spread operator
function getStatusObject():StatusObject {
let statusObject: StatusObject = Object.entries(Status).reduce((acc, [_str, status]) => {
return Object.assign(acc, {[status]: status.toLowerCase()})
// The initial value {} must be typecasted so that a TS compiling error does not occur
}, {} as StatusObject)
return statusObject
}