[英]How to narrow object type based on field presence?
我有 2 個類似的端點,一個用於獲取列表,另一個用於獲取過濾列表。 現在不可能通過后端的查詢參數將它們合並到一個端點中。 所以我有一個函數可以根據 id 字段的存在來決定使用哪個端點。 問題是我無法獲得正確的類型推斷,無法縮小args
。
怎么做? 也許,最好使用聯合,但我看不到判別場?
export interface Arguments {
id?: number;
token?: string;
pageSize: number;
}
function requestTo1stEndpoint(a: {
id: number;
token?: string;
pageSize: number;
}) {
return Promise.resolve(1);
}
function requestTo2ndEndpoint(a: {
token?: string;
pageSize: number;
}) {
return Promise.resolve(2);
}
async function request(args: Arguments) {
let fun: typeof requestTo1stEndpoint | typeof requestTo2ndEndpoint
if (args.id !== undefined) {
fun = requestTo1stEndpoint
} else
fun = requestTo2ndEndpoint
const response = await fun(args)
}
這也不起作用:
async function request(args: Arguments) {
let responsePromise: Response
// this doesn't work either
// if ('id' in args)
if (args.id !== undefined) {
// cannot be narrowed
responsePromise = requestTo1stEndpoint(args)
} else
responsePromise = requestTo2ndEndpoint(args)
const response = await responsePromise
}
您可以使用User Defined Type Guard 和“in” Narrowing來做到這一點。
為了完成這項工作,我們還需要在使用類型保護的if
的true
或false
中包含依賴於args
類型的代碼。 這是因為編譯器“知道”如果true
部分執行它是Type1
,而在 else 中它不是Type1
。
interface Type1{
id: number;
token?: string;
pageSize: number;
}
interface Type2 {
token?: string;
pageSize: number;
}
function isType1(x: Type1 | Type2): x is Type1 {
if ('id' in x) return true;
return false;
}
function requestTo1stEndpoint(a: Type1) {
return Promise.resolve(1);
}
function requestTo2ndEndpoint(a: Type2) {
return Promise.resolve(2);
}
async function request(args: Type1 | Type2) {
const response = isType1(args) ? await requestTo1stEndpoint(args) : await requestTo2ndEndpoint(args);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.