typescript에서`payload is T`를 반환 할 때 올바른 유형을 추론하는 방법은 무엇입니까?

Mesqueeb

JavaScript에 값이 약속인지 아닌지 알려주는 유형 가드 검사 기능이 있으며 동시에 변수가 약속임을 TypeScript에 알려줍니다.

function getType (payload: any): string {
  return Object.prototype.toString.call(payload).slice(8, -1)
}    

function isPromise (payload: any): payload is Promise<any> {
  return getType(payload) === 'Promise'
}

하지만 정말 잘 작동하지만 약속 해결을 하드 코딩하지 any않고 대신 해당 유형을 추론 해야한다는 것을 깨달았습니다 .

이것이 any제대로 작동하지 않는 이유는 다음과 같습니다.

export type PlainObject = { [key: string]: any }
let a: PlainObject | PlainObject[] | Promise<PlainObject | PlainObject[]>
let b = isPromise(a) ? await a : a

이 예에서는 ... 이어야하는 동안 b으로 추론됩니다 .PlainObjectPlainObject | PlainObject[]

질문 1 : 왜 이런 일이 발생합니까?

더 나은 isPromise기능 에서 시도한 솔루션 :

type Unpacked<T> =
    T extends (infer U)[] ? U :
    T extends (...args: any[]) => infer U ? U :
    T extends Promise<infer U> ? U :
    T;

function isPromise2 <T extends any>(payload: T): payload is Promise<Unpacked<T>> {
  return getType(payload) === 'Promise'
}

이론적으로 나는 이것이 작동하지 않는 이유를 알지 못합니다. 하지만이 오류가 발생합니다.

유형 술어의 유형은 매개 변수 유형에 할당 할 수 있어야합니다. 'Promise>'유형은 'T'유형에 할당 할 수 없습니다. 'Promise>'는 'T'유형의 제약 조건에 할당 할 수 있지만 'T'는 제약 조건 'any'의 다른 하위 유형으로 인스턴스화 될 수 있습니다.

질문 2 :payload is Promise<Unpacked<T>> 작동 하지 않는 이유는 무엇 이며 그렇지 않으면 어떻게 추론 할 수 있습니까?

TypeScript PlayGround의 위의 모든 내용은 다음과 같습니다.

https://www.typescriptlang.org/v2/en/play?#code/KYDwDg9gTgLgBDAnmYcAKAbAhgSwHYDyARgFbADG8AvHAN5wDaA1sIgFxwDOMU+A5gF0OWPIjgBfAFCSAZgFc8lHBDxw+wGABVkqABRgsiDBCwATYaICUHbrzx86kuHCga5UVcTKUAdGCgQMIE6PkEAyjz8PuRYGBj6hsZmlj6cGDjkwLoAHAA0cAC0AIyWkuLOztLyijDKqjicaAEAtg16BkYm5nAiiNZwHUmmcA3oLW0APL0AfI7OrjDuqupaOgmdyXBU23AA5E0QrZzAu2XSGBo9HJi4hKQU8AA+6Nj4Xg8MAnDPB0fAEzc3vdKN8Xrd3pRPtNJBd4EQtiNGuNjrosJY4AB+HoAd1w8CwcGE0gA9MS4NiABZYeAASRcwFiGDEuLw8CCcFMEERbEkSBQcAAqngDOQWKYJppZlQnBVNHBQDBgHhTJw4Lp8DJgFBBZZPpjBYSZc45QqlSq1T5LVgoHxOBZEJ90VRZhqtQasQLDRU4CaQIrlarfpNXdqBbMPV7ZQBuKoKJQqRFB44AJjgEvlfrNqpm6yGHE0-UGXURY0OkyFIrFEums1oMoWSzUGm0KFzXSdO32yJOZyAA

ford04

1 : 왜 이런 일이 발생합니까?

PlainObject[]하위 유형 입니다 PlainObject. 당신은 노동 조합이있는 경우 세트 이론적으로, Subtype | Supertype다음 결과 유형이 될 것입니다 Supertype- 그것은 흡수한다 Subtype . 그래서 여기에 b입력 PlainObject하십시오.

PlainObject[]하위 유형입니까? 우리가 볼 때 그것은 명확 얻을 수 ArrayPlainObject유형 :

interface Array<T> { [n: number]: T} // T is PlainObject for PlainObject[]
type PlainObject = { [key: string]: any }

JS에서 number속성 키는 string. 그리고 T그것이 무엇이든 상관없이 any.

type PlainObjArr_extends_PlainObj  = PlainObject[] extends PlainObject ? true : false // true

2 : 페이로드가 Promise> 작동하지 않는 이유는 무엇이며 그렇지 않으면 어떻게 추론 할 수 있습니까?

사용자 정의 유형 가드의 경우 유형 술어 ( is xxx)는 확인 된 인수 하위 유형 이어야합니다 . TS는 여기서 확인할 수 없습니다 . Promise<Unpacked<T>>이는의 하위 유형입니다 T. 그 사실을 무시, isPromise 하지 의 작업이 모두 호환되지 않는 값을 필터링 a:

let b = isPromise(a) ? await a /*Promise<PObj | PObj[]>*/ : a /*PObj | PObj[]*/

any-자주-악한 사람입니다 : o). 솔루션을 만드는 것입니다 PlainObject[]호환에를 PlainObject:

export type PlainObject = { [key: string]: unknown } // e.g. replace `any` by `unknown`
let b = isPromise(a) ? await a : a  // b: PlainObject | PlainObject[]

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

콘텐츠 유형이 올바른 경우에만 프록시에서 응답을 반환하도록 nginx를 구성하는 방법은 무엇입니까?

분류에서Dev

R에서 데이터를 내보낼 때 Year-Mon 문자열을 올바른 날짜 형식으로 변환하는 방법은 무엇입니까?

분류에서Dev

Extern "C"의 벡터 <std :: string>에 List <String ^>을 (를) 반환하는 올바른 방법은 무엇입니까?

분류에서Dev

DELETE를 수행 할 수 없을 때 반환 할 올바른 http 상태 코드는 무엇입니까?

분류에서Dev

Typescript에서 클래스를 유형으로 사용할 때 순환 종속성을 해결하는 방법은 무엇입니까?

분류에서Dev

동일한 입력에 대해 다른 유형을 반환 할 수있는 확장 메서드를 작성하는 방법은 무엇입니까?

분류에서Dev

TryGetValue를 사용할 때 사전 값을 업데이트하는 올바른 방법은 무엇입니까?

분류에서Dev

Frame.Navigate를 사용할 때 올바른 뒤로 동작을 구현하는 방법은 무엇입니까?

분류에서Dev

다른 유형을 다형 적으로 반환 할 수있는 C ++에서 팩토리 메서드를 만드는 방법은 무엇입니까?

분류에서Dev

ConcurrentDictionary에서 일부 항목을 제거하려고 할 때 올바른 방법은 무엇입니까?

분류에서Dev

XPath 유효성 검사기가 올바른 결과를 반환 할 때 XmlNode.SelectNodes가 빈 목록을 반환하는 이유는 무엇입니까?

분류에서Dev

react-router에서 동일한 수준의 경로를 전환 할 때 데이터를 가져 오는 올바른 방법은 무엇입니까?

분류에서Dev

php-exec ()를 사용할 때 mysqldump에서 반환을 얻는 방법은 무엇입니까?

분류에서Dev

fsharp에서 정말 다른 유형을 반환하는 함수를 만드는 방법은 무엇입니까?

분류에서Dev

UPDATE를 사용할 때 MySQL에서 열을 변수 값으로 설정하는 올바른 방법은 무엇입니까?

분류에서Dev

페이지로 유연하게 크기를 조정할 때 메인 콘텐츠에 오른쪽 사이드 바를 올리는 방법은 무엇입니까?

분류에서Dev

"원시 유형"을 정적 필드 / 반환 유형으로 사용할 때 제네릭 경고를 피하는 방법은 무엇입니까?

분류에서Dev

삽입 함수와 같은 것에서 부울을 반환하는 올바른 방법은 무엇입니까?

분류에서Dev

반응으로 렌더링 할 때 객체에 전환을 추가하는 방법은 무엇입니까?

분류에서Dev

Comparator.comparing에서 형식 매개 변수를 올바르게 추론하는 방법은 무엇입니까?

분류에서Dev

매개 변수를 전달할 때 일반 유형을 보존하는 방법은 무엇입니까?

분류에서Dev

bytea 데이터 유형을 사용할 때 YugaByteDB YSQL 선택 쿼리가 예기치 않은 바이트를 반환하는 이유는 무엇입니까?

분류에서Dev

Varnish에 사이트를 추가 할 때 반복 sed 명령을 피하는 방법은 무엇입니까?

분류에서Dev

배열을 입력 할 때 올바른 결과를 반환하지 않는 방법

분류에서Dev

컴파일러가 유형을 추론 할 수있을 때 함수에 유형 서명을 사용하는 좋은 이유는 무엇입니까?

분류에서Dev

Java에서 다른 반환 유형을 추상화하는 방법은 무엇입니까?

분류에서Dev

Rest 웹 서비스 요청에서 파일을 반환하는 올바른 방법은 무엇입니까?

분류에서Dev

조명기에서 구조화 된 데이터를 반환하는 올바른 방법은 무엇입니까?

분류에서Dev

Rails API에서 올바른 필드를 반환하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    콘텐츠 유형이 올바른 경우에만 프록시에서 응답을 반환하도록 nginx를 구성하는 방법은 무엇입니까?

  2. 2

    R에서 데이터를 내보낼 때 Year-Mon 문자열을 올바른 날짜 형식으로 변환하는 방법은 무엇입니까?

  3. 3

    Extern "C"의 벡터 <std :: string>에 List <String ^>을 (를) 반환하는 올바른 방법은 무엇입니까?

  4. 4

    DELETE를 수행 할 수 없을 때 반환 할 올바른 http 상태 코드는 무엇입니까?

  5. 5

    Typescript에서 클래스를 유형으로 사용할 때 순환 종속성을 해결하는 방법은 무엇입니까?

  6. 6

    동일한 입력에 대해 다른 유형을 반환 할 수있는 확장 메서드를 작성하는 방법은 무엇입니까?

  7. 7

    TryGetValue를 사용할 때 사전 값을 업데이트하는 올바른 방법은 무엇입니까?

  8. 8

    Frame.Navigate를 사용할 때 올바른 뒤로 동작을 구현하는 방법은 무엇입니까?

  9. 9

    다른 유형을 다형 적으로 반환 할 수있는 C ++에서 팩토리 메서드를 만드는 방법은 무엇입니까?

  10. 10

    ConcurrentDictionary에서 일부 항목을 제거하려고 할 때 올바른 방법은 무엇입니까?

  11. 11

    XPath 유효성 검사기가 올바른 결과를 반환 할 때 XmlNode.SelectNodes가 빈 목록을 반환하는 이유는 무엇입니까?

  12. 12

    react-router에서 동일한 수준의 경로를 전환 할 때 데이터를 가져 오는 올바른 방법은 무엇입니까?

  13. 13

    php-exec ()를 사용할 때 mysqldump에서 반환을 얻는 방법은 무엇입니까?

  14. 14

    fsharp에서 정말 다른 유형을 반환하는 함수를 만드는 방법은 무엇입니까?

  15. 15

    UPDATE를 사용할 때 MySQL에서 열을 변수 값으로 설정하는 올바른 방법은 무엇입니까?

  16. 16

    페이지로 유연하게 크기를 조정할 때 메인 콘텐츠에 오른쪽 사이드 바를 올리는 방법은 무엇입니까?

  17. 17

    "원시 유형"을 정적 필드 / 반환 유형으로 사용할 때 제네릭 경고를 피하는 방법은 무엇입니까?

  18. 18

    삽입 함수와 같은 것에서 부울을 반환하는 올바른 방법은 무엇입니까?

  19. 19

    반응으로 렌더링 할 때 객체에 전환을 추가하는 방법은 무엇입니까?

  20. 20

    Comparator.comparing에서 형식 매개 변수를 올바르게 추론하는 방법은 무엇입니까?

  21. 21

    매개 변수를 전달할 때 일반 유형을 보존하는 방법은 무엇입니까?

  22. 22

    bytea 데이터 유형을 사용할 때 YugaByteDB YSQL 선택 쿼리가 예기치 않은 바이트를 반환하는 이유는 무엇입니까?

  23. 23

    Varnish에 사이트를 추가 할 때 반복 sed 명령을 피하는 방법은 무엇입니까?

  24. 24

    배열을 입력 할 때 올바른 결과를 반환하지 않는 방법

  25. 25

    컴파일러가 유형을 추론 할 수있을 때 함수에 유형 서명을 사용하는 좋은 이유는 무엇입니까?

  26. 26

    Java에서 다른 반환 유형을 추상화하는 방법은 무엇입니까?

  27. 27

    Rest 웹 서비스 요청에서 파일을 반환하는 올바른 방법은 무엇입니까?

  28. 28

    조명기에서 구조화 된 데이터를 반환하는 올바른 방법은 무엇입니까?

  29. 29

    Rails API에서 올바른 필드를 반환하는 방법은 무엇입니까?

뜨겁다태그

보관