itsource

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

mycopycode 2022. 9. 11. 17:36
반응형

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

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

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"유니온 타입의 옵션에 있는 특정 키에 대해"를 의미합니다.

type에일리어스는 보다 유연하고 강력합니다.interface.

클래스에서 사용할 필요가 없는 경우type에 걸쳐서interface.

내 경우:

export type PossibleKeysType =
  | 'userAgreement'
  | 'privacy'
  | 'people';

interface ProviderProps {
  children: React.ReactNode;
  items: {
    //   ↙ this colon was issue
    [key: PossibleKeysType]: Array<SectionItemsType>;
  };
}

를 사용하여 수정했습니다.in사용하는 대신 연산자:

~~~

interface ProviderProps {
  children: React.ReactNode;
  items: {
    //     ↙ use "in" operator
    [key in PossibleKeysType]: Array<SectionItemsType>;
  };
}

비슷한 문제가 있었습니다만, 인터페이스의 다른 필드 속성에 관한 것이었기 때문에, 옵션의 필드 속성에 키의 열거를 가지는 예를 들면, 솔루션으로서 다음과 같습니다.

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

저도 비슷한 문제가 있었어요.Angular Form Validator를 만들 때 특정 키만 사용하려고 했습니다.

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개의 키를 사용할 수 있습니다.

저도 비슷한 문제에 직면했습니다. 이 간단한 해결책을 찾았습니다. 이 솔루션은 저에게 매력적으로 작용했습니다. 간단히 []를 ()로 대체하십시오.

interface OptionRequirements {
  (key: Option): OptionRequirement;
}

제 경우 열거형이 아닌 결합형을 사용해야 했지만 둘 다 잘 작동합니다.

type DocumentId = 'invoiceId' | 'orderId';

export interface INote {
    id: number;
    organizationId: number;
    (key: DocumentId): number;
    //...
}

언급URL : https://stackoverflow.com/questions/54438012/an-index-signature-parameter-type-cannot-be-a-union-type-consider-using-a-mappe

반응형