itsource

숫자 열거형을 사용하여 유형 스크립트 '기록 <>

mycopycode 2023. 7. 1. 08:35
반응형

숫자 열거형을 사용하여 유형 스크립트 '기록 <>

유형 스크립트에서 문자열 열거형으로 레코드 유형을 만들 수 있습니다.

enum AxisLabel { X = "X", Y = "Y" }
export const labelLookup: Record<AxisLabel, string> = {
  [AxisLabel.X]: "X axis",
  [AxisLabel.Y]: "Y Axis"
};

다음을 생성해야 합니다.Record위의 개체와 유사하지만 문자열 열거형을 사용하지 않습니다.

제가 이런 시도를 할 때:

enum AxisLabel { X, Y }
export const labelLookup: Record<AxisLabel, string> = {
  [AxisLabel.X]: "X axis",
  [AxisLabel.Y]: "Y Axis"
};

유형 스크립트에서 다음 오류가 발생합니다.

Type 'AxisLabel' does not satisfy the constraint 'string'.

멤버 이름으로 숫자와 문자열을 모두 사용하여 JS 개체를 만들 수 있습니다.

저는 타입스크립트에서 동일하게 하고 싶지만 안전하지 않은 강제나 타입캐스트에 의존하지 않습니다.문자열 열거형 또는 유형 캐스트를 사용하지 않고 유형 스크립트에서 숫자 열거형 레코드 <> 유형을 만들려면 어떻게 해야 합니까?

업데이트: TypeScript 2.9 지원 추가number그리고.symbol따라서 위의 코드는 더 이상 오류를 제공하지 않으며, TypeScript 2.9 이상을 사용하는 한 이 대답은 더 이상 필요하지 않습니다.

TypeScript 2.8 이하의 경우:


JavaScript의 객체 키는 믿거나 말거나 배열에 대해서도 항상 문자열(OK 또는 s)입니다.문자열이 아닌 값을 키로 전달하면 먼저 문자열로 강제 전달됩니다.그러나 물론 사람들은 숫자 키가 특히 배열에 적합할 것으로 기대합니다.TypeScript는 이러한 일관성 없는 철학을 반영합니다. 일반적으로 문자열 값 키만 지정할 수 있습니다(예: 다음과 같은 매핑된 유형).Record<K,V>그런 상황들이 상호작용할 때 여러분은 이상해집니다.

다음 튜플 유형을 사용하여 숫자에서 문자열로의 강제를 명시적으로 나타냅니다.

export type NumericStrings = ["0","1","2","3","4","5","6","7","8","9","10"] // etc

필요한 만큼 확장할 수 있습니다.그런 다음 조회 유형을 사용하여 숫자 유형을 매핑된 유형에 사용할 문자열로 변환할 수 있습니다.이와 같은 경우:

export enum AxisLabel { X, Y }

// note the key is NumericStrings[AxisLabel], not AxisLabel    
export const labelLookup: Record<NumericStrings[AxisLabel], string> = {
  [AxisLabel.X]: "X axis",
  [AxisLabel.Y]: "Y Axis"
};

그것은 오류 없이 작동합니다.의 유형을 검사하는 경우labelLookup로 표시됩니다.Record<"0" | "1", string>색인화를 시도할 때labelLookup다음과 같이 대부분 예상되는 일이 발생합니다.

labelLookup[AxisLabel.X]; // okay
labelLookup[0]; // okay
labelLookup["0"]; // also okay

labelLookup[10]; // error
labelLookup.X; //error

도움이 되길 바랍니다; 행운을 빕니다!

레코드의 정의는 매우 구체적이어서 키를 문자열에 할당할 수 있어야 하므로 사용할 방법이 없습니다.Record숫자가 있는 경우, 더 일반적으로 매핑된 유형의 키는 문자열이어야 합니다.

일반 인덱스 서명을 사용할 수는 있지만 인덱스 서명을 문자열 또는 숫자(언어 사양에 따라) 이외의 항목으로 제한할 수는 없습니다. 즉, 열거형 값뿐만 아니라 모든 숫자도 유효합니다.

export const labelLookup: { [index: number]: string } = {
    [AxisLabel.X]: "X axis",
    [AxisLabel.Y]: "Y Axis",
    [3] = "" // Also works but you don't want that
};

을 enum의 일부로 하는 또 은 enum입니다.Record

enum AxisLabel { X, Y }
export const labelLookup: Record<AxisLabel[keyof AxisLabel & number], string> = {
  [AxisLabel.X]: "X axis",
  [AxisLabel.Y]: "Y Axis"
}

OR

enum AxisLabel { X, Y }
type XorY = typeof AxisLabel.X | typeof AxisLabel.Y
export const labelLookup: Record<XorY, string> = {
  [AxisLabel.X]: "X axis",
  [AxisLabel.Y]: "Y Axis"
}

언급URL : https://stackoverflow.com/questions/47776364/creating-a-typescript-record-type-with-numeric-enums

반응형