[javascript] 인덱스 서명 매개 변수 유형은 공용체 유형이 될 수 없습니다. 대신 매핑 된 개체 유형을 사용하는 것이 좋습니다.

다음 패턴을 사용하려고합니다.

enum Option {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three'
}

interface OptionRequirement {
  someBool: boolean;
  someString: string;
}

interface OptionRequirements {
  [key: Option]: OptionRequirement;
}

이것은 나에게 매우 간단 해 보이지만 다음과 같은 오류가 발생합니다.

인덱스 서명 매개 변수 유형은 공용체 유형이 될 수 없습니다. 대신 매핑 된 개체 유형을 사용하는 것이 좋습니다.

내가 도대체 ​​뭘 잘못하고있는 겁니까?



답변

TS “in”연산자를 사용하여 다음을 수행 할 수 있습니다.

enum Options {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three',
}
interface OptionRequirement {
  someBool: boolean;
  someString: string;
}
type OptionRequirements = {
  [key in Options]: OptionRequirement; // Note that "key in".
}


답변

가장 간단한 해결책은 Record

type OptionRequirements = Record<Options, OptionRequirement>

다음과 같이 직접 구현할 수도 있습니다.

type OptionRequirements = {
  [key in Options]: OptionRequirement;
}

이 구성은에서만 사용할 수 type있지만 사용할 수 없습니다 interface.

당신의 정의의 문제는 인터페이스의 키 유형을 사용해야 말하고 Options, Options열거가 아닌 문자열, 숫자 또는 기호입니다.

key in Options“노조 유형 옵션에서의 그 특정 키의”를 의미한다.

typealias는보다 유연하고 강력합니다 interface.

당신의 타입이 클래스에서 사용 할 필요가없는 경우, 선택 type이상 interface.


답변

비슷한 문제가 있었지만 내 경우에는 인터페이스의 다른 필드 속성이 있으므로 키에 대한 열거 형이있는 선택적 필드 속성이있는 예제와 같은 솔루션이 있습니다 .

export enum ACTION_INSTANCE_KEY {
  cat = 'cat',
  dog = 'dog',
  cow = 'cow',
  book = 'book'
}

type ActionInstances = {
  [key in ACTION_INSTANCE_KEY]?: number; // cat id/dog id/cow id/ etc // <== optional
};

export interface EventAnalyticsAction extends ActionInstances { // <== need to be extended
  marker: EVENT_ANALYTIC_ACTION_TYPE; // <== if you wanna add another field to interface
}


답변

인터페이스를 사용하는 대신 매핑 된 개체 유형을 사용하십시오.

enum Option {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three'
}

type OptionKeys = keyof typeof Option;

interface OptionRequirement {
  someBool: boolean;
  someString: string;
}

type OptionRequirements = {                 // note type, not interface
  [key in OptionKeys]: OptionRequirement;   // key in
}


답변

제 경우에는 속성이 선택 사항이 필요했기 때문에이 일반 유형을 만들었습니다.

type PartialRecord<K extends string | number | symbol, T> = { [P in K]?: T; };

그런 다음 다음과 같이 사용하십시오.

type MyTypes = 'TYPE_A' | 'TYPE_B' | 'TYPE_C';

interface IContent {
    name: string;
    age: number;
}

interface IExample {
    type: string;
    partials: PartialRecord<MyTypes, IContent>;
}

const example : IExample = {
    type: 'some-type',
    partials: {
        TYPE_A : {
            name: 'name',
            age: 30
        },
        TYPE_C : {
            name: 'another name',
            age: 50
        }
    }
}


답변

비슷한 문제가있었습니다. 각도 양식 유효성 검사기를 만들 때 특정 키만 사용하려고했습니다.

export enum FormErrorEnum {
  unknown = 'unknown',
  customError = 'customError',
}

export type FormError = keyof typeof FormErrorEnum;

그리고 사용법 :

static customFunction(param: number, param2: string): ValidatorFn {
  return (control: AbstractControl): { [key: FormErrorEnum]?: any } => {
    return { customError: {param, param2} };
  };
}

이렇게하면 1-X 개의 키를 사용할 수 있습니다.


답변