簡體   English   中英

如何在TypeScript中添加編譯時?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM