[英]How can I do compile-time addition in TypeScript?
如何在TypeScript的類型系統中添加?
我可以得到后繼者(加1)和前任者(減1),但是還沒有弄清楚如何獲得所需的遞歸以便一般將兩個數字相加:
type Z = 0 // zero
type S<T> = { item: T } // successor
type P<T extends S<any>> = T['item'] // predecessor
type N = S<any> | Z // number, not exactly right because S<boolean> isn't a number
const zero = 0
const one: S<Z> = { item: 0 }
const two: S<S<Z>> = { item: { item: 0} }
const three: S<S<S<Z>>> = { item: { item: { item: 0 } } }
const predPred3: P<P<typeof three>> = one; // OK
我遇到的問題是遞歸類型定義:
// Error: Type alias 'Plus' circularly references itself
type Plus<T1, T2> = T2 extends Z ? T1 : Plus<T1, P<T2>>
我試圖通過使用ReturnType
來解決問題,但語法甚至不正確:
function plus<T1 extends N, T2 extends N>(t1: T1, t2: T2) : T2 extends Z ? T1 : ReturnType<typeof plus<T1, P<T2>>> {
return t2 === 0? t1 : plus({item: t1}, (t2 as S<any>).item);
}
有沒有辦法在類型系統中做加法?
為了規避“類型別名'Plus'循環引用自身”的限制,您必須在對象成員類型中引用遞歸類型,然后使用[]
作為索引類型訪問運算符來選擇適當的成員類型:
type Plus<T1, T2> = {
z: T1;
s: T2 extends S<any> ? S<Plus<T1, P<T2>>> : never
// conditional type necessary because compiler can't figure out
// that T2 always extends S here, "never" branch is never taken
}[T2 extends Z ? 'z' : 's']
const p12: Plus<typeof one, typeof two> = three; // typechecks
但是,請注意此評論
除非像@ahejlsberg這樣的人可以告訴我們,是否可以期望像這樣的事情能夠繼續工作
它很聰明,但是絕對可以使事情超出預期的用途。 盡管它可能適用於一些小例子,但它的規模將非常驚人。 解決這些深度遞歸類型會消耗大量時間和資源,並且將來可能會影響我們在檢查器中使用的遞歸調控器。
別做!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.