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
으로 추론됩니다 .PlainObject
PlainObject | 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의 위의 모든 내용은 다음과 같습니다.
1 : 왜 이런 일이 발생합니까?
PlainObject[]
의 하위 유형 입니다 PlainObject
. 당신은 노동 조합이있는 경우 세트 이론적으로, Subtype | Supertype
다음 결과 유형이 될 것입니다 Supertype
- 그것은 흡수한다 Subtype
. 그래서 여기에 b
입력 PlainObject
하십시오.
왜 PlainObject[]
하위 유형입니까? 우리가 볼 때 그것은 명확 얻을 수 Array
및 PlainObject
유형 :
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] 삭제
몇 마디 만하겠습니다