programing

다른 속성을 허용하는 TypeScript 인터페이스

nicescript 2023. 2. 11. 16:34
반응형

다른 속성을 허용하는 TypeScript 인터페이스

요약하면 일부 기본 속성을 선언하지만 추가 속성을 제한하지 않는 인터페이스를 가질 수 있습니까?이것이 저의 현재 상황입니다.

범용 디스패처를 정의하는 플럭스 패턴을 사용하고 있습니다.

class Dispatcher<TPayload> {
    dispatch(arg:TPayload):void { }
}

그런 다음 다음과 같이 자체 페이로드 유형을 사용하여 디스패처를 만듭니다.

interface ActionPayload {
    actionType: string
}

const dispatcher = new Dispatcher<ActionPayload>();

추가 데이터와 함께 페이로드를 디스패치하는 액션코드가 몇 개 있습니다만ActionPayload인터페이스에서는actionType즉, 이 코드는 다음과 같습니다.

interface SomePayload extends ActionPayload {
    someOtherData: any
}

class SomeActions {
    doSomething():void {
        dispatcher.dispatch({
            actionType: "hello",
            someOtherData: {}
        })
    }
}

컴파일 에러를 표시합니다.someOtherData일치하지 않습니다.ActionPayload인터페이스입니다.문제는 많은 다른 "액션" 클래스가 동일한 디스패처를 재사용하기 때문에 이 클래스는someOtherData여기 있을지도 몰라anotherKindOfData저기, 기타 등등.지금으로서는 이 상황에 대응하기 위해 할 수 있는 것은new Dispatcher<any>()다른 액션이 디스패치 되기 때문입니다.모든 작업이 베이스를 공유합니다.ActionPayload하지만, 그래서 저는 이런 타입을 구속할 수 있기를 바랐습니다.new Dispatcher<extends ActionPayload>()뭐 그런 거.그런 게 가능해요?

네가 원한다면ActionPayload인덱서를 추가할 수 있는 다른 속성을 수락하려면:

interface ActionPayload {
    actionType: string;

    // Keys can be strings, numbers, or symbols.
    // If you know it to be strings only, you can also restrict it to that.
    // For the value you can use any or unknown, 
    // with unknown being the more defensive approach.
    [x: string | number | symbol]: unknown;
}

https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#strict-object-literal-assignment-checking 를 참조해 주세요.

interface Options {
  darkMode?: boolean;
  [otherOptions: string]: unknown;
  }

이런 걸 만들어서 해결했어요.

type Make = "Volvo" | "Polestar" | "Saab";
interface BaseCar {
    make: Make;
    horsePower: number;
    allWheelDrive: boolean;
}
type Car = BaseCar & Record<string, string|number|boolean>;

오브젝트 정의에서 타입을 유추한 경우 타입을 원래 타입과 조합하여 지정할 수 있습니다.{[key: string]: any]}:

const obj = { foo: 42 };
return obj as typeof obj & {[key: string]: any]};

이 방법으로 IntelliSense는 다음과 같이 제안합니다.foo그러나 다른 키를 할당하거나 가져오려고 해도 불평하지 않습니다.

추가 키가 적고 priori로 알려진 경우 유형 정의에서 옵션으로 추가할 수 있습니다.

const obj: {foo: number; bar?: string} = {foo: 42}

TypeScript 3.9+를 사용하여 다음과 같이 설정합니다.truetsconfig.json승인된 답변에 오류가 발생합니다.

해결책은 다음과 같습니다.


interface ActionPayload {
    actionType: string;

    // choose one or both depending on your use case
    // also, you can use `unknown` as property type, as TypeScript promoted type, 
    // but it will generate errors if you iterate over it
    [x: string]: any;
    [x: number]: any;
}

이것에 의해, 다음과 같은 에러가 회피됩니다.

  • An index signature parameter type must be either 'string' or 'number'.
    • symbol허용되지 않습니다.
  • An index signature parameter type cannot be a union type. Consider using a mapped object type instead.
    • string | number에 들어갈 수 없습니다.[x: string | number]: unknown;

내가 찾던 걸 찾은 것 같아.디스패치된 오브젝트를 다음에 던질 수 있습니다.SomePayload및 TSC는 그것이 캐스트인터페이스와 호환성이 있는지 확인합니다.TPayload디스패처:

    dispatcher.dispatch(<SomePayload>{
        actionType: "hello",
        someOtherData: {}
    })

온라인 예

언급URL : https://stackoverflow.com/questions/33836671/typescript-interface-that-allows-other-properties

반응형