W12D1 Typescript Enum Exercise

Jin Bae·2023년 1월 31일
0

스파르타코딩클럽

목록 보기
29/35

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.

Using the in expression

The 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
}

Using the 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;
//}

Using 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
}

0개의 댓글