简体   繁体   English

如何在TypeScript中添加编译时?

[英]How can I do compile-time addition in TypeScript?

How can I do addition in the type system in TypeScript? 如何在TypeScript的类型系统中添加?

I can get successor (add 1) and predecessor (subtract 1) but haven't figured out how to get the recursion needed in order to add two numbers generally: 我可以得到后继者(加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

The problem I'm hitting is with recursive type definitions: 我遇到的问题是递归类型定义:

// Error: Type alias 'Plus' circularly references itself
type Plus<T1, T2> = T2 extends Z ? T1 : Plus<T1, P<T2>>

I tried to hack around the problem by using ReturnType but the syntax isn't even correct: 我试图通过使用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);
}

Is there a way to do addition in the type system? 有没有办法在类型系统中做加法?

To evade "Type alias 'Plus' circularly references itself" restriction, you have to reference recursive type in the object member type, then select appropriate member type using [] as indexed type access operator : 为了规避“类型别名'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

However, be warned by this comment 但是,请注意此评论

unless someone like @ahejlsberg can tell us if we can expect things like that to keep working or not 除非像@ahejlsberg这样的人可以告诉我们,是否可以期望像这样的事情能够继续工作

It's clever, but it definitely pushes things well beyond their intended use. 它很聪明,但是绝对可以使事情超出预期的用途。 While it may work for small examples, it will scale horribly. 尽管它可能适用于一些小例子,但它的规模将非常惊人。 Resolving those deeply recursive types consumes a lot of time and resources and might in the future run afoul of the recursion governors we have in the checker. 解决这些深度递归类型会消耗大量时间和资源,并且将来可能会影响我们在检查器中使用的递归调控器。

Don't do it! 别做!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM