>source

다음 유형이 정의 된 라이브러리를 사용하고 있습니다 :

type VoidableCallback<EventValue> = EventValue extends void ? () => void : (val: EventValue) => void;

라이브러리는 위의 타입을 반환하는 함수를 노출합니다 :

declare function fn<T>(): VoidableCallback<T>;

이 기능을 차별적 인 노조와 함께 사용하고 싶습니다 :

type Action = { type: 'add'; n: number } | { type: 'multiply'; n: number };
const callback = fn<Action>();
callback({ type: 'add', n: 1 });

그러나 Typescript (3.4.1)에서 다음과 같은 오류 메시지가 나타납니다 :

Type '"add"' is not assignable to type '"add" & "multiply"'. Type '"add"' is not assignable to type '"multiply"'.ts(2322)

The expected type comes from property 'type' which is declared here on type '{ type: "add"; n: number; } & { type: "multiply"; n: number; }'

이 이유를 이해할 수 없습니다. 합계 (유니온) 유형이 '제품'유형으로 해석되는 것 같습니다.

유형 정의를 다음과 같이 변경하면 :

type VoidableCallback<EventValue> = (val: EventValue) => void;

... Typescript가 불평하지 않습니다. 따라서 조건부 유형 및 공용체 유형과 관련이 있습니다.

여기에서 무슨 일이 일어나고 있는지 이해할 수 있다면, 도서관에 홍보 할 수있을 것입니다. ( rxjs 후크 ).

  • 답변 # 1

    이것은 조건부 유형의 분산 동작으로 인해 발생합니다. 조건부 유형은 기본 유형 매개 변수에 분산됩니다. 즉, type 매개 변수에 공용체가 포함 된 경우 조건부 형식이 공용체의 각 멤버에 적용되고 결과는 모든 응용 프로그램의 공용체가됩니다. 그래서 당신의 경우에 우리는 VoidableCallback<{ type: 'add'; n: number } | { type: 'multiply'; n: number }> = VoidableCallback<{ type: 'add'; n: number }> | VoidableCallback<{ type: 'multiply'; n: number }> = ((val: { type: 'add'; n: number }) => void) | ((val: { type: 'multiply'; n: number }) => void) 를 얻을 것입니다  여기에서이 동작에 대해 읽을 수 있습니다

    교차에 대해 오류가 발생하는 이유는 typescript가 함수 시그니처의 공용체를 처리하는 방식이기 때문입니다. 기본적으로 매개 변수가 호환되어야하며 모든 공용체의 시그니처가 호환되어야합니다. . 여기에 대해 읽을 수 있습니다

    간단한 해결책은 조건부 유형에 대한 배포를 비활성화하는 것입니다. 튜플에 type 매개 변수를 배치하면 쉽게 수행 할 수 있습니다.

    type VoidableCallback<EventValue> = [EventValue] extends [void] ? () => void : (val: EventValue) => void;
    type Action = { type: 'add'; n: number } | { type: 'multiply'; n: number };
    declare function fn<T>(): VoidableCallback<T>;
    const callback = fn<Action>();
    callback({ type: 'add', n: 1 }); //ok now
    
    

    운동장 링크

관련 자료

  • 이전 php - google app engine, 2 서비스, dispatchyaml - nginx-appconf가 더 이상 고려되지 않는 것 같습니다
  • 다음 python 3.x - 셀러리의 처리되지 않은 예외로 작업자가 동결 됨