[英]Typescript - inherit return type from the argument property when argument is union
我有一個類型,它是通用接口與 2 個通用類型的聯合。 其中一個是枚舉,另一個對於每個枚舉值都不同。
調用 function 時,TS 根據 function 調用中的枚舉值正確識別數據類型,但不明白返回值應該與 ZA8CFDE6331BD49EB2AC96F8911 的屬性之一相同的類型
代碼:
interface Base<D = any, T = string> {
data: D;
type: T;
}
enum BaseTypes {
foo,
bar,
boo,
}
type BaseSet = Base<number, BaseTypes.foo> | Base<string, BaseTypes.bar> | Base<{d: number}, BaseType.boo>;
function processData(payload: BaseSet): typeof payload.data {
return payload.data;
}
// a type should be number
// but it's number | string
const a = processData({ data: 1, type: BaseTypes.foo });
我的理解是a
的類型應該從有效負載數據類型繼承,在這種情況下應該是string
。 我的兩個問題是:
processData
function 不是通用的 function。 它接受一個 object 參數,該參數是兩種BaseSet
類型中的一種。
它的返回類型為typeof payload.data
。 關鍵的區別是: payload
的類型是什么? 在這個版本中, payload
的類型是聯合類型BaseSet
,因此返回類型typeof payload.data
payload.data 是BaseSet
中所有data
類型的聯合。
這是因為我們在執行processData(payload: BaseSet)
時將payload
的類型設置為BaseSet
。 如果我們有關於該payload
變量類型的更具體信息,該信息就會丟失。 為了為payload
保留更具體的類型,我們需要使用 generics。
我們可以將processData
設為通用 function 並說返回的類型取決於調用它的 arguments 的類型。 這里我使用泛型D
來指代data
屬性的類型。
function processData<D>(payload: BaseSet & {data: D}): D {
return payload.data;
}
我們說payload
必須具有類型{data: D}
並且也是有效的BaseSet
。 這會強制執行配對,但也允許 typescript 推斷data
的更具體的版本類型。 然后我們說這個特定的類型將是我們的返回類型。
測試它,我們得到正確的返回類型,如果data
和type
不匹配,也會出現錯誤。
const a = processData({ data: 1, type: BaseTypes.foo }); // number
const b = processData({ data: "hahaha", type: BaseTypes.foo }); // error
const c = processData({ data: "hahaha", type: BaseTypes.bar }); // string
有多種方法可以定義通用 function。 泛型是data
類型還是整個payload
類型? 我們應該對D
應用任何約束還是& BaseSet
就足夠了? 有趣的是,這個版本給了我文字字符串和數字作為返回類型。
function processData<D extends BaseSet['data']>(payload: BaseSet & {data: D}): D {
return payload.data;
}
const a = processData({ data: 1, type: BaseTypes.foo }); // 1
const b = processData({ data: "hahaha", type: BaseTypes.foo }); // error
const c = processData({ data: "hahaha", type: BaseTypes.bar }); // "hahaha"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.