TypeScript allows you to compose recursive types but gives no insight into how the code changes in lower levels (i.e. depths). The code below, for example, would have the same kind of signature across all levels, and we would have to manually check at each level that there exists a sub
property.
type Recurse = { foo: string; sub?: Recurse }
function recurse(depth: number): Recurse {
if (depth === 0) return { foo: 'hey' }
return {
foo: 'hey',
sub: recurse(depth - 1),
}
}
const qux = recurse(5)
What I am seeking is a type signature that would give us concrete evidence of what the function returned at a particular depth.
const qux0: { foo: string } = recurse(0)
const qux1: { foo: string, sub: { foo: string } } = recurse(1)
const qux2: { foo: string, sub: { foo: string, sub: { foo: string }} } = recurse(2)
This way, we would not have to check at every level for the sub
property as the type signature already packs that information.
I have a feeling that this might be possible to achieve with conditional types but have no concrete evidence.
Do you have any idea how I could achieve that?
The recursion depth limit in Python is by default 1000 . You can change it using sys. setrecursionlimit() function.
Abstract. The maximum depth of recursion refers to the number of levels of activation of a procedure which exist during the deepest call of the procedure.
partial recursive function A function on the natural numbers that can be obtained from certain initial functions by a finite number of applications of composition, primitive recursion, and minimization.
The maximal recursion depth is limited by JavaScript engine. We can rely on it being 10000, some engines allow more, but 100000 is probably out of limit for the majority of them.
Until TS allows basic arithmetic operations for number
types, you can use a decrement counter like Decr
for all recursive types with particular depth:
type Decr = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // add to a reasonable amount
type Recurse<N extends number> = N extends 0 ?
{ foo: string } :
{ foo: string; sub: Recurse<Decr[N]> }
function recurse<N extends number>(depth: N): Recurse<N> {
if (depth === 0) return { foo: 'hey' } as Recurse<N>
return {
foo: 'hey',
sub: recurse(depth - 1),
} as Recurse<N>
}
type Decr9 = Decr[9] // 8
// compiles now
const qux = recurse(5)
const qux0: { foo: string } = recurse(0)
const qux1: { foo: string, sub: { foo: string } } = recurse(1)
const qux2: { foo: string, sub: { foo: string, sub: { foo: string } } } = recurse(2)
Sample
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With