String-literal Union Types to Array 또는: 행성 목록에서 명왕성을 쫓아내는 방법

10989 단어 typescript
Pluto ! 한때 우리 태양계의 9개 행성 목록에 포함되었던 이 행성은 이제 왜행성으로 간주됩니다. 누가 그 목록이 바뀔 것이라고 생각했습니까? 그리고 명왕성이 난쟁이 이상으로 다시 생각된다면 Planet Nine의 이름은 어떻게 될까요?

태양계와 유사하게 일부 코드 또는 마스터 데이터가 변경되지 않을 것으로 예상되는 경우가 있습니다. 하지만 그럴 때,
  • ["Pluto"]는 종종 드롭다운 목록 등을 위해 배열에 하드코딩됩니다.
  • {"Pluto": {"discovered":1930, "namedAfter": "Pluto"}}는 복잡한 json 개체의 키 또는 값에서 찾을 수 있습니다
  • .
  • 또는 function getLegendFromMythologyByDeity(f: "Pluto" | "Flora" | "Juno" | "Apollo" | "Minerva" | "Diana" | "Vulcan" | "Sol")의 매개변수입니다.



  • 따라서 상황을 개선하기 위해 이러한 유형을 손으로 채울 수 있습니다. 문자열 리터럴 유형이라고 하며 해당 항목에 대해 자세히 설명합니다here.

    export type PlanetsType: "Mercury" | "Venus" | "Earth" | "Mars" | "Jupiter" | "Saturn" | "Uranus" 
      | "Neptune"; 
      //| "Pluto";
    export type MythologicalDeityType: "Pluto" | "Flora" | "Juno" | "Apollo" | "Minerva" | "Diana" | "Vulcan" | "Sol";
    export type MickeysFriendsType: "Pluto" | "Minnie" | "Donald";
    


    문자열 리터럴 공용체 유형의 가능한 모든 순열을 포함하는 배열을 추가로 원하는 경우 직접 채울 수 있습니다.

    export const PlanetsTypeKeys: PlanetsType[] = [
      "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus"
      , "Neptune"];
    


    ...하지만 새 문자열 리터럴 유형이 해당 공용체에 들어갈 때마다 업데이트해야 한다는 것을 기억해야 합니다.

    export type PlanetsType: "Mercury" | "Venus" | "Earth" | "Mars" | "Jupiter" | "Saturn" | "Uranus" 
      | "Neptune" 
      | "Planet9TheMisterious"; // <-- the new one, now the array has to be updated
    


    자체 유지 솔루션



    코드의 "올바른 부분"을 업데이트하는 것을 기억하는 것은 일반적으로 주석을 남기더라도 어렵습니다. 따라서 유형 오류를 던지는 것이 훨씬 낫습니다. 통합 유형(컴파일 시간 - typescript)에서 배열(런타임 - javascript)을 생성할 수 없기 때문에 헬퍼를 사용하여 마침내 마스터로 돌아갑니다. 데이터.

    /**
     * PlanetsType is a union type of string literals. This is useful for making switch-case statements exhaustive:
     * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
     * 
     * below however, we want to get an exhaustive list of all string literals in the union type. By building a helper
     * object with the key set to "s in PlanetsType", we effectively create an enum-like structure with all the
     * string literals of PlanetsType. When you create or change PlanetsType, this helps to keep the 
     * array in PlanetsTypeKeys up-to-date by throwing a typing error. The order of the entries is also preserved
     */
    const PlanetsTypeHelperObj: { [s in PlanetsType ]: PlanetsType } = {
      "Mercury":"Mercury",
      "Venus":"Venus",
      "Earth":"Earth",
      "Mars":"Mars",
      "Jupiter":"Jupiter",
      "Saturn":"Saturn",
      "Uranus":"Uranus",
      "Neptune":"Neptune",
      //"Pluto":"Pluto",
      "Planet9TheMisterious":"Planet9TheMisterious",
    }
    
    export const PlanetsTypeKeys: PlanetsType[] = Object.keys(PlanetsTypeHelperObj) as PlanetsType[]
    


    이렇게 하면 PlanetsTypeKeys가 typescript에서 문자열 리터럴의 전체 배열로 바뀝니다. json 개체(이 사용법에서는 "사전"이라고도 함)를 기반으로 하기 때문에 중복이 없습니다. 마지막으로 json 개체( {"VenusKey":"VenusValue"} )의 값 측면은 원하는 모든 것이 될 수 있습니다. 값 부분을 마스터 데이터로 만들려면 PlanetsTypeKeys가 최신 상태로 유지되고 사용할 준비가 됩니다. 예를 들어 드롭다운이 있습니다.

    좋은 웹페이지 즐겨찾기