如何在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);
}
有没有办法在类型系统中做加法运算?
答案 0 :(得分:3)
要避免“类型别名'Plus'循环引用自身”的限制,您必须在对象成员类型中引用递归类型,然后使用[]
作为indexed type access operator选择适当的成员类型:
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
不过,请注意this comment
除非@ahejlsberg这样的人可以告诉我们是否可以期待 这样就可以继续工作
这很聪明,但绝对可以将事情推向极限 有可能的使用。虽然它可能适用于一些小例子,但可以扩展 太可怕了解决那些深度递归类型会消耗很多 时间和资源,并且将来可能会影响递归 检查器中有多个州长。
不要这样做!